home *** CD-ROM | disk | FTP | other *** search
Text File | 2006-06-30 | 119.5 KB | 3,536 lines |
- #!/usr/bin/python -O
- # Copyright 1999-2006 Gentoo Foundation
- # Distributed under the terms of the GNU General Public License v2
- # $Id: /var/cvsroot/gentoo-src/portage/bin/emerge,v 1.345.2.38 2005/08/13 17:25:26 ferringb Exp $
-
- import os,sys
- os.environ["PORTAGE_CALLER"]="emerge"
- sys.path = ["/usr/lib/portage/pym"]+sys.path
- import errno
-
- try:
- import portage
- except KeyboardInterrupt:
- sys.exit(1) # If they control C during imports, just die silently
-
- import emergehelp,xpak,string,re,commands,time,shutil,traceback,signal,socket,types
- from stat import *
- from output import *
-
- import portage_util
- import portage_locks
- import portage_exception
- from portage_const import PROFILE_PATH
-
- portage.global_updates(
- portage.settings, portage.db, portage.mtimedb["updates"])
-
- spinner_msgs = ["Gentoo Rocks ("+os.uname()[0]+")",
- "Thank you for using Gentoo. :)",
- "Are you actually trying to read this?",
- "How many times have you stared at this?",
- "We are generating the cache right now",
- "You are paying too much attention.",
- "A theory is better than its explanation.",
- "Phasers locked on target, Captain.",
- "Thrashing is just virtual crashing.",
- "To be is to program.",
- "Real Users hate Real Programmers.",
- "When all else fails, read the instructions.",
- "Functionality breeds Contempt.",
- "The future lies ahead.",
- "3.1415926535897932384626433832795028841971694",
- "Sometimes insanity is the only alternative.",
- "Inaccuracy saves a world of explanation.",
- ]
-
-
- def update_basic_spinner():
- global spinner, spinpos
- spinpos = (spinpos+1) % 500
- if (spinpos % 100) == 0:
- if spinpos == 0:
- sys.stdout.write(". ")
- else:
- sys.stdout.write(".")
- sys.stdout.flush()
-
- def update_scroll_spinner():
- global spinner, spinpos
- if(spinpos >= len(spinner)):
- sys.stdout.write(darkgreen(" \b\b\b"+spinner[len(spinner)-1-(spinpos%len(spinner))]))
- else:
- sys.stdout.write(green("\b "+spinner[spinpos]))
- sys.stdout.flush()
- spinpos = (spinpos+1) % (2*len(spinner))
-
- def update_twirl_spinner():
- global spinner, spinpos
- spinpos = (spinpos+1) % len(spinner)
- sys.stdout.write("\b\b "+spinner[spinpos])
- sys.stdout.flush()
-
- def update_quiet_spinner():
- return
-
- spinpos = 0
- spinner = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|"
- update_spinner = update_twirl_spinner
- if "candy" in portage.settings.features:
- spinner = spinner_msgs[int(time.time()*100)%len(spinner_msgs)]
- update_spinner = update_scroll_spinner
-
- # To enhance usability, make some vars case insensitive by forcing them to
- # lower case.
- portage.settings.unlock()
- for myvar in ("AUTOCLEAN", "NOCOLOR"):
- if myvar in portage.settings:
- portage.settings[myvar] = portage.settings[myvar].lower()
- portage.settings.backup_changes(myvar)
- portage.settings.lock()
- del myvar
-
- if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes","true"]):
- nocolor()
-
-
-
- def normpath(mystr):
- """
- os.path.normpath("//foo") returns "//foo" instead of "/foo"
- We dislike this behavior so we create our own normpath func
- to fix it.
- """
- if mystr and (mystr[0]=='/'):
- return os.path.normpath("///"+mystr)
- else:
- return os.path.normpath(mystr)
-
- def userquery(prompt, responses=None, colours=None):
- """Displays a prompt and a set of responses, then waits for a response
- which is checked against the responses and the first to match is
- returned. An empty response will match the first value in responses. The
- input buffer is *not* cleared prior to the prompt!
-
- prompt: a String.
- responses: a List of Strings.
- colours: a List of Functions taking and returning a String, used to
- process the responses for display. Typically these will be functions
- like red() but could be e.g. lambda x: "DisplayString".
- If responses is omitted, defaults to ["Yes", "No"], [green, red].
- If only colours is omitted, defaults to [bold, ...].
-
- Returns a member of the List responses. (If called without optional
- arguments, returns "Yes" or "No".)
- KeyboardInterrupt is converted to SystemExit to avoid tracebacks being
- printed."""
- if responses is None:
- responses, colours = ["Yes", "No"], [green, red]
- elif colours is None:
- colours=[bold]
- colours=(colours*len(responses))[:len(responses)]
- print bold(prompt),
- try:
- while True:
- response=raw_input("["+string.join([colours[i](responses[i]) for i in range(len(responses))],"/")+"] ")
- for key in responses:
- # An empty response will match the first value in responses.
- if response.upper()==key[:len(response)].upper():
- return key
- print "Sorry, response '%s' not understood." % response,
- except (EOFError, KeyboardInterrupt):
- print "Interrupted."
- sys.exit(1)
-
- def sorted_versions(verlist):
- ret = []
- for ver in verlist:
- verparts = ver.split("-")
- if len(verparts) == 2:
- verrev = int(verparts[1][1:])
- else:
- verrev = 0
- x = 0
- while x < len(ret):
- retparts = ret[x].split("-")
- verdiff = portage.vercmp(retparts[0], verparts[0])
- if verdiff > 0:
- break
- elif verdiff == 0:
- if len(retparts) == 2:
- retrev = int(retparts[1][1:])
- else:
- retrev = 0
- if retrev >= verrev:
- break
- x += 1
- ret.insert(x, ver)
- return ret
-
- portage.deprecated_profile_check()
-
- if portage.settings.has_key("PORTAGE_NICENESS"):
- try:
- os.nice(int(portage.settings["PORTAGE_NICENESS"]))
- except (OSError,ValueError), e:
- print "!!! Failed to change nice value to '"+str(portage.settings["PORTAGE_NICENESS"])+"'"
- print "!!!",e
-
- #Freeze the portdbapi for enhanced performance:
- portage.portdb.freeze()
-
- # Kill noauto as it will break merges otherwise.
- if "noauto" in portage.settings.features:
- while "noauto" in portage.settings.features:
- portage.settings.features.remove("noauto")
- portage.settings.unlock()
- portage.settings["FEATURES"] = " ".join(portage.settings.features)
- portage.settings.backup_changes("FEATURES")
- portage.settings.lock()
-
- #number of ebuilds merged
- merged=0
- params=["selective", "deep", "self", "recurse", "empty"]
- actions=[
- "clean", "config", "depclean",
- "info", "metadata",
- "prune", "regen", "search",
- "sync", "system", "unmerge", "world",
- ]
- options=[
- "--ask", "--alphabetical",
- "--buildpkg", "--buildpkgonly",
- "--changelog", "--columns", "--cols",
- "--debug", "--deep",
- "--digest",
- "--emptytree",
- "--fetchonly", "--fetch-all-uri",
- "--getbinpkg", "--getbinpkgonly",
- "--help", "--ignore-default-opts",
- "--noconfmem",
- "--newuse", "--nocolor",
- "--nodeps", "--noreplace",
- "--nospinner", "--oneshot",
- "--onlydeps", "--pretend",
- "--quiet", "--resume",
- "--searchdesc", "--selective",
- "--skipfirst", "--skip-first",
- "--tree",
- "--update",
- "--usepkg", "--usepkgonly",
- "--verbose", "--version"
- ]
-
- shortmapping={
- "1":"--oneshot",
- "a":"--ask",
- "b":"--buildpkg", "B":"--buildpkgonly",
- "c":"--clean", "C":"--unmerge",
- "d":"--debug", "D":"--deep",
- "e":"--emptytree",
- "f":"--fetchonly", "F":"--fetch-all-uri",
- "g":"--getbinpkg", "G":"--getbinpkgonly",
- "h":"--help",
- "k":"--usepkg", "K":"--usepkgonly",
- "l":"--changelog",
- "n":"--noreplace", "N":"--newuse",
- "o":"--onlydeps", "O":"--nodeps",
- "p":"--pretend", "P":"--prune",
- "q":"--quiet",
- "s":"--search", "S":"--searchdesc",
- 't':"--tree",
- "u":"--update",
- "v":"--verbose", "V":"--version"
- }
-
- myaction=None
- myopts=[]
- myfiles=[]
- edebug=0
-
- # process short actions
- tmpcmdline=sys.argv[1:]
- if "--ignore-default-opts" not in tmpcmdline:
- tmpcmdline.extend(portage.settings["EMERGE_DEFAULT_OPTS"].split())
- cmdline=[]
- for x in tmpcmdline:
- if x[0:1]=="-" and x[1:2]!="-":
- for y in x[1:]:
- if shortmapping.has_key(y):
- if shortmapping[y] in cmdline:
- print
- print "*** Warning: Redundant use of",shortmapping[y]
- else:
- cmdline.append(shortmapping[y])
- else:
- print "!!! Error: -"+y+" is an invalid short action or option."
- sys.exit(1)
- else:
- cmdline.append(x)
-
- # process the options and command arguments
- for x in cmdline:
- if not x:
- continue
- if len(x)>=2 and x[0:2]=="--":
- if x == "--cols":
- x = "--columns"
- elif x == "--skip-first":
- x = "--skipfirst"
- if x in options:
- if x not in myopts:
- myopts.append(x)
- elif x[2:] in actions:
- if myaction:
- if myaction not in ["system", "world"]:
- myaction="--"+myaction
- print
- print red("!!!")+green(" Multiple actions requested... Please choose one only.")
- print red("!!!")+" '"+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
- print
- sys.exit(1)
- myaction=x[2:]
- else:
- print "!!! Error:",x,"is an invalid option."
- sys.exit(1)
- elif (not myaction) and (x in actions):
- if x not in ["system", "world"]:
- print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
- if myaction:
- print
- print red("!!!")+green(" Multiple actions requested... Please choose one only.")
- print red("!!! '")+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
- print
- sys.exit(1)
- myaction=x
- elif x[-1]=="/":
- # this little conditional helps tab completion
- myfiles.append(x[:-1])
- else:
- myfiles.append(x)
-
-
- if "moo" in myfiles:
- print """
-
- Larry loves Gentoo (""" + os.uname()[0] + """)
-
- _______________________
- < Have you mooed today? >
- -----------------------
- \ ^__^
- \ (oo)\_______
- (__)\ )\/\
- ||----w |
- || ||
-
- """
-
- if (myaction in ["world", "system"]) and myfiles:
- print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both."
- sys.exit(1)
-
- for x in myfiles:
- ext = os.path.splitext(x)[1]
- if (ext == ".ebuild" or ext == ".tbz2") and os.path.exists(os.path.abspath(x)):
- print "emerging by path implies --oneshot... adding --oneshot to options."
- print red("\n*** emerging by path is broken and may not always work!!!\n")
- break
-
- if ("--tree" in myopts) and ("--columns" in myopts):
- print "emerge: can't specify both of \"--tree\" and \"--columns\"."
- sys.exit(1)
-
- if ("--quiet" in myopts):
- update_spinner = update_quiet_spinner
- portage_util.noiselimit = -1
- portage.settings.unlock()
- portage.settings["PORTAGE_QUIET"]="1"
- portage.settings.backup_changes("PORTAGE_QUIET")
- portage.settings.lock()
-
- # Always create packages if FEATURES=buildpkg
- # Imply --buildpkg if --buildpkgonly
- if ("buildpkg" in portage.settings.features) or ("--buildpkgonly" in myopts):
- if "--buildpkg" not in myopts:
- myopts.append("--buildpkg")
-
- # --tree only makes sense with --pretend
- if "--tree" in myopts and not (("--pretend" in myopts) or ("--ask" in myopts)):
- print ">>> --tree implies --pretend... adding --pretend to options."
- myopts.append("--pretend")
-
- # Also allow -S to invoke search action (-sS)
- if ("--searchdesc" in myopts):
- if myaction and myaction != "search":
- myfiles.append(myaction)
- if "--search" not in myopts:
- myopts.append("--search")
- myaction = "search"
-
- # Always try and fetch binary packages if FEATURES=getbinpkg
- if ("getbinpkg" in portage.settings.features):
- myopts.append("--getbinpkg")
-
- if "--skipfirst" in myopts and "--resume" not in myopts:
- myopts.append("--resume")
-
- if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts):
- myopts.append("--usepkgonly")
-
- if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts):
- myopts.append("--getbinpkg")
-
- if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts):
- myopts.append("--usepkg")
-
- # Also allow -K to apply --usepkg/-k
- if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts):
- myopts.append("--usepkg")
-
- if ("--newuse" in myopts) and not ("--update" in myopts):
- print ">>> --newuse implies --update... adding --update to options."
- myopts.append("--update")
-
- # Also allow -l to apply --pretend/-p, but if already in --ask mode
- if ("--changelog" in myopts) and not (("--pretend" in myopts) or ("--ask" in myopts)):
- print ">>> --changelog implies --pretend... adding --pretend to options."
- myopts.append("--pretend")
-
- # Allow -p to remove --ask
- if ("--pretend" in myopts) and ("--ask" in myopts):
- print ">>> --pretend disables --ask... removing --ask from options."
- myopts.remove("--ask")
-
- # forbid --ask when not in a terminal
- # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway.
- if ("--ask" in myopts) and (not sys.stdin.isatty()):
- portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n",
- noiselevel=-1)
- sys.exit(1)
-
- # Set so that configs will be merged regardless of remembered status
- if ("--noconfmem" in myopts):
- portage.settings.unlock()
- portage.settings["NOCONFMEM"]="1"
- portage.settings.backup_changes("NOCONFMEM")
- portage.settings.lock()
-
- # Set various debug markers... They should be merged somehow.
- if ("--debug" in myopts):
- portage.settings.unlock()
- portage.settings["PORTAGE_DEBUG"]="1"
- portage.settings.backup_changes("PORTAGE_DEBUG")
- portage.debug=1
- portage.settings.lock()
- if "python-trace" in portage.settings.features:
- import portage_debug
- portage_debug.set_trace(True)
-
- if ("--resume" in myopts):
- if "--tree" in myopts:
- print "* --tree is currently broken with --resume. Disabling..."
- myopts.remove("--tree")
-
- # Set color output
- if "--nocolor" in myopts or \
- portage.settings["NOCOLOR"] in ("yes","true"):
- nocolor()
- if "NOCOLOR" not in portage.settings:
- portage.settings.unlock()
- portage.settings["NOCOLOR"] = "true"
- portage.settings.backup_changes("NOCOLOR")
- portage.settings.lock()
-
- if not ("--quiet" in myopts):
- if not sys.stdout.isatty() or ("--nospinner" in myopts):
- update_spinner = update_basic_spinner
-
- CLEAN_DELAY = 5
- EMERGE_WARNING_DELAY = 10
- if portage.settings["CLEAN_DELAY"]:
- CLEAN_DELAY = string.atoi("0"+portage.settings["CLEAN_DELAY"])
- if portage.settings["EMERGE_WARNING_DELAY"]:
- EMERGE_WARNING_DELAY = string.atoi("0"+portage.settings["EMERGE_WARNING_DELAY"])
-
- def emergelog(mystr,short_msg=None):
- if "notitles" not in portage.settings.features:
- if short_msg:
- xtermTitle(short_msg)
- else:
- xtermTitle(mystr)
- try:
- #seems odd opening a file each write...
- if not os.path.exists("/var/log/emerge.log"):
- mylogfile=open("/var/log/emerge.log", "w")
- os.chmod("/var/log/emerge.log", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
- os.chown("/var/log/emerge.log", portage.portage_uid, portage.portage_gid)
- else:
- mylogfile=open("/var/log/emerge.log", "a")
-
- l=portage_locks.lockfile(mylogfile)
- # seek because we may have gotten held up by the lock.
- # if so, we may not be positioned at the end of the file.
- mylogfile.seek(0,2)
- mylogfile.write(str(time.time())[:10]+": "+mystr+"\n")
- mylogfile.flush()
- portage_locks.unlockfile(l)
- mylogfile.close()
- except (IOError,OSError,portage_exception.PortageException), e:
- if edebug:
- print "emergelog():",e
- pass
-
- def emergeexit():
- """This gets out final log message in before we quit."""
- if "--pretend" not in myopts:
- emergelog(" *** terminating.")
- if "notitles" not in portage.settings.features:
- xtermTitleReset()
- portage.atexit_register(emergeexit)
-
- def emergeexitsig(signum, frame):
- signal.signal(signal.SIGINT, signal.SIG_IGN)
- portage.portageexit()
- portage_util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum})
- sys.exit(100+signum)
- signal.signal(signal.SIGINT, emergeexitsig)
-
- def countdown(secs=5, doing="Starting"):
- if secs:
- print ">>> Waiting",secs,"seconds before starting..."
- print ">>> (Control-C to abort)...\n"+doing+" in: ",
- ticks=range(secs)
- ticks.reverse()
- for sec in ticks:
- sys.stdout.write(red(str(sec+1)+" "))
- sys.stdout.flush()
- time.sleep(1)
- print
-
- # formats a size given in bytes nicely
- def format_size(mysize):
- if type(mysize) not in [types.IntType,types.LongType]:
- return str(mysize)
- mystr=str(mysize/1024)
- mycount=len(mystr)
- while (mycount > 3):
- mycount-=3
- mystr=mystr[:mycount]+","+mystr[mycount:]
- return mystr+" kB"
-
-
- def getgccversion():
- """
- rtype: C{str}
- return: the current in-use gcc version
- """
-
- gcc_ver_command = 'gcc -dumpversion'
- gcc_ver_prefix = 'gcc-'
-
- gcc_not_found_error = red(
- "!!! No gcc found. You probably need to 'source /etc/profile'\n" +
- "!!! to update the environment of this terminal and possibly\n" +
- "!!! other terminals also.\n"
- )
-
- mystatus, myoutput = commands.getstatusoutput("eselect compiler show")
- if mystatus == os.EX_OK and len(myoutput.split("/")) == 2:
- part1, part2 = myoutput.split("/")
- if len(part1.split("-")) > 0:
- return gcc_ver_prefix + part1.split("-")[-1] + "/" + part2
-
- mystatus, myoutput = commands.getstatusoutput("gcc-config -c")
- if mystatus == os.EX_OK and len(myoutput.split("-")) > 0:
- return gcc_ver_prefix + myoutput.split("-")[-1]
-
- mystatus, myoutput = commands.getstatusoutput(
- portage.settings["CHOST"] + "-" + gcc_ver_command)
- if mystatus == os.EX_OK:
- return gcc_ver_prefix + myoutput
-
- mystatus, myoutput = commands.getstatusoutput(gcc_ver_command)
- if mystatus == os.EX_OK:
- return gcc_ver_prefix + myoutput
-
- portage.writemsg(gcc_not_found_error, noiselevel=-1)
- return "[unavailable]"
-
- def getportageversion():
- try:
- import re
- profilever = os.path.normpath("///"+os.readlink(PROFILE_PATH))
- basepath = os.path.normpath("///"+portage.settings["PORTDIR"]+"/profiles")
- if re.match(basepath,profilever):
- profilever = profilever[len(basepath)+1:]
- else:
- profilever = "!"+profilever
- del basepath
- except (OSError,IOError):
- profilever="unavailable"
- libcver=[]
- libclist = portage.vardbapi(portage.root).match("virtual/libc")
- libclist += portage.vardbapi(portage.root).match("virtual/glibc")
- libclist = portage_util.unique_array(libclist)
- for x in libclist:
- xs=portage.catpkgsplit(x)
- if libcver:
- libcver+=","+string.join(xs[1:], "-")
- else:
- libcver=string.join(xs[1:], "-")
- if libcver==[]:
- libcver="unavailable"
-
- gccver = getgccversion()
- unameout=os.uname()[2]+" "+os.uname()[4]
-
- return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", "+libcver+", "+unameout+")"
-
- def help():
- # Move all the help stuff out of this file.
- emergehelp.help(myaction,myopts,havecolor)
-
- if "--version" in myopts:
- print getportageversion()
- sys.exit(0)
- elif "--help" in myopts:
- help()
- sys.exit(0)
-
- if portage.wheelgid == portage.portage_gid:
- print "emerge: wheel group use is being deprecated. Please update group and passwd to"
- print " include the portage user as noted above, and then use group portage."
-
- if "--debug" in myopts:
- print "myaction", myaction
- print "myopts", myopts
-
- if not myaction and not myfiles and "--resume" not in myopts:
- help()
- sys.exit(1)
-
- # check if root user is the current user for the actions where emerge needs this
- if portage.secpass < 2:
- # We've already allowed "--version" and "--help" above.
- if "--pretend" not in myopts and \
- myaction not in ("search","info"):
- if portage.secpass >= 1:
- if "--fetchonly" not in myopts and \
- "--fetch-all-uri" not in myopts and \
- myaction not in ("metadata", "regen"):
- print "emerge: root access required."
- sys.exit(1)
- else:
- print "emerge: root access required."
- sys.exit(1)
-
- if not "--pretend" in myopts:
- emergelog("Started emerge on: "+time.strftime("%b %d, %Y %H:%M:%S", time.localtime()))
- myelogstr=""
- if myopts:
- myelogstr=string.join(myopts, " ")
- if myaction:
- myelogstr+=" "+myaction
- if myfiles:
- myelogstr+=" "+string.join(myfiles, " ")
- emergelog(" *** emerge "+myelogstr)
-
- #configure emerge engine parameters
- #
- # self: include _this_ package regardless of if it is merged.
- # selective: exclude the package if it is merged
- # recurse: go into the dependencies
- # empty: pretend nothing is merged
- myparams=["self","recurse"]
- add=[]
- sub=[]
- if "--update" in myopts or myaction in ("system", "world"):
- add.extend(["selective","empty"])
- if "--emptytree" in myopts:
- add.extend(["empty"])
- sub.extend(["selective"])
- if "--nodeps" in myopts:
- sub.extend(["recurse"])
- if "--noreplace" in myopts:
- add.extend(["selective"])
- if "--deep" in myopts:
- add.extend(["deep"])
- if "--selective" in myopts:
- add.extend(["selective"])
- if myaction in ["world","system"]:
- add.extend(["selective"])
- elif myaction in ["depclean"]:
- add.extend(["empty"])
- sub.extend(["selective"])
- for x in add:
- if (x not in myparams) and (x not in sub):
- myparams.append(x)
- for x in sub:
- if x in myparams:
- myparams.remove(x)
-
- # search functionality
- class search:
-
- #
- # class constants
- #
- VERSION_SHORT=1
- VERSION_RELEASE=2
-
- #
- # public interface
- #
- def __init__(self):
- """Searches the available and installed packages for the supplied search key.
- The list of available and installed packages is created at object instantiation.
- This makes successive searches faster."""
- self.installcache = portage.db["/"]["vartree"]
-
- def execute(self,searchkey):
- """Performs the search for the supplied search key"""
- global myopts
- match_category = 0
- self.searchkey=searchkey
- self.packagematches = []
- if "--searchdesc" in myopts:
- self.searchdesc=1
- self.matches = {"pkg":[], "desc":[]}
- else:
- self.searchdesc=0
- self.matches = {"pkg":[]}
- print "Searching... ",
-
- if self.searchkey[0] == '@':
- match_category = 1
- self.searchkey = self.searchkey[1:]
- if self.searchkey=="*":
- #hack for people who aren't regular expression gurus
- self.searchkey==".*"
- if re.search("\+\+", self.searchkey):
- #hack for people who aren't regular expression gurus
- self.searchkey=re.sub("\+\+","\+\+",self.searchkey)
- self.searchre=re.compile(self.searchkey.lower(),re.I)
- for package in portage.portdb.cp_all():
- update_spinner()
-
- if match_category:
- match_string = package[:]
- else:
- match_string = package.split("/")[-1]
-
- masked=0
- if self.searchre.search(match_string):
- if not portage.portdb.xmatch("match-visible",package):
- masked=1
- self.matches["pkg"].append([package,masked])
- elif self.searchdesc: # DESCRIPTION searching
- full_package = portage.portdb.xmatch("bestmatch-visible",package)
- if not full_package:
- #no match found; we don't want to query description
- full_package=portage.best(portage.portdb.xmatch("match-all",package))
- if not full_package:
- continue
- else:
- masked=1
- try:
- full_desc = portage.portdb.aux_get(full_package,["DESCRIPTION"])[0]
- except KeyError:
- print "emerge: search: aux_get() failed, skipping"
- continue
- if self.searchre.search(full_desc):
- self.matches["desc"].append([full_package,masked])
- self.mlen=0
- for mtype in self.matches.keys():
- self.matches[mtype].sort()
- self.mlen += len(self.matches[mtype])
-
- def output(self):
- """Outputs the results of the search."""
- print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]"
- print "[ Applications found : "+white(str(self.mlen))+" ]"
- print " "
- for mtype in self.matches.keys():
- for match,masked in self.matches[mtype]:
- if mtype=="pkg":
- catpack=match
- full_package = portage.portdb.xmatch("bestmatch-visible",match)
- if not full_package:
- #no match found; we don't want to query description
- masked=1
- full_package=portage.best(portage.portdb.xmatch("match-all",match))
- else:
- full_package = match
- match = portage.pkgsplit(match)[0]
-
- if full_package:
- try:
- desc, homepage, license = portage.portdb.aux_get(full_package,["DESCRIPTION","HOMEPAGE","LICENSE"])
- except KeyError:
- print "emerge: search: aux_get() failed, skipping"
- continue
- if masked:
- print green("*")+" "+white(match)+" "+red("[ Masked ]")
- else:
- print green("*")+" "+white(match)
- myversion = self.getVersion(full_package, search.VERSION_RELEASE)
-
- mysum = [0,0]
- mycat = match.split("/")[0]
- mypkg = match.split("/")[1]
- mycpv = match + "-" + myversion
- myebuild = portage.portdb.findname(mycpv)
- pkgdir = os.path.dirname(myebuild)
- import portage_manifest
- mf = portage_manifest.Manifest(
- pkgdir, portage.settings["DISTDIR"])
- fetchlist = portage.portdb.getfetchlist(mycpv,
- mysettings=portage.settings, all=True)[1]
- try:
- mysum[0] = mf.getDistfilesSize(fetchlist)
- mystr = str(mysum[0]/1024)
- mycount=len(mystr)
- while (mycount > 3):
- mycount-=3
- mystr=mystr[:mycount]+","+mystr[mycount:]
- mysum[0]=mystr+" kB"
- except KeyError, e:
- mysum[0] = "Unknown (missing digest for %s)" % str(e)
-
- if "--quiet" not in myopts:
- print " ", darkgreen("Latest version available:"),myversion
- print " ", self.getInstallationStatus(mycat+'/'+mypkg)
- print " ", darkgreen("Size of files:"),mysum[0]
- print " ", darkgreen("Homepage:")+" ",homepage
- print " ", darkgreen("Description:")+" ",desc
- print " ", darkgreen("License:")+" ",license
- print
- print
- #
- # private interface
- #
- def getInstallationStatus(self,package):
- installed_package = self.installcache.dep_bestmatch(package)
- result = ""
- version = self.getVersion(installed_package,search.VERSION_RELEASE)
- if len(version) > 0:
- result = darkgreen("Latest version installed:")+" "+version
- else:
- result = darkgreen("Latest version installed:")+" [ Not Installed ]"
- return result
-
- def getVersion(self,full_package,detail):
- if len(full_package) > 1:
- package_parts = portage.catpkgsplit(full_package)
- if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
- result = package_parts[2]+ "-" + package_parts[3]
- else:
- result = package_parts[2]
- else:
- result = ""
- return result
-
-
- #build our package digraph
- def getlist(mode):
- if mode=="system":
- mylines=portage.settings.packages
- elif mode=="world":
- try:
- myfile = open(os.path.join(portage.root, portage.WORLD_FILE), "r")
- mylines=myfile.readlines()
- myfile.close()
- except OSError:
- print "!!! Couldn't open "+pfile+"; exiting."
- sys.exit(1)
- except IOError, e:
- #Permission denied is a fatal error, as opposed to a missing file
- if e.errno == errno.EACCES:
- raise
- else:
- if "--quiet" not in myopts:
- portage.writemsg(red("\n!!! ") + "Warning %s does not exist.\n" % os.path.join(portage.root, portage.WORLD_FILE) )
- mylines=[]
- mynewlines=[]
- for x in mylines:
- myline=string.join(string.split(x))
- if not len(myline):
- continue
- elif myline[0]=="#":
- continue
- elif mode=="system":
- if myline[0]!="*":
- continue
- myline=myline[1:]
- mynewlines.append(myline.strip())
-
- # Remove everything that is package.provided from our list
- for atom in mynewlines[:]:
- for expanded_atom in portage.flatten(portage.dep_virtual([atom], portage.settings)):
- mykey = portage.dep_getkey(expanded_atom)
- if portage.settings.pprovideddict.has_key(mykey) and \
- portage.match_from_list(expanded_atom, portage.settings.pprovideddict[mykey]):
- mynewlines.remove(atom)
- break
-
- return mynewlines
-
- def genericdict(mylist):
- mynewdict={}
- for x in mylist:
- mynewdict[portage.dep_getkey(x)]=x
- return mynewdict
-
- olddbapi=None
- class depgraph:
-
- def __init__(self,myaction,myopts):
- global olddbapi
- self.pkgsettings = portage.config(clone=portage.settings)
- if not self.pkgsettings["ARCH"]:
- portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"),
- noiselevel=-1)
- portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"),
- noiselevel=-1)
- sys.exit(9)
- self.applied_useflags = {}
-
- self.missingbins=[]
- self.myaction=myaction
- self.digraph=portage.digraph()
- self.orderedkeys=[]
- self.outdatedpackages=[]
- self.mydbapi={}
- self.mydbapi["/"] = portage.fakedbapi()
- if "empty" not in myparams or portage.root != "/":
- for pkg in portage.db["/"]["vartree"].getallcpv():
- self.mydbapi["/"].cpv_inject(pkg)
- if portage.root != "/":
- self.mydbapi[portage.root] = portage.fakedbapi()
- if "empty" not in myparams:
- for pkg in portage.db[portage.root]["vartree"].getallcpv():
- self.mydbapi[portage.root].cpv_inject(pkg)
-
- if "--usepkg" in myopts:
- portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts))
-
- def create(self,mybigkey,myparent=None,addme=1,myuse=None):
- """creates the actual digraph of packages to merge. return 1 on success, 0 on failure
- mybigkey = specification of package to merge; myparent = parent package (one depending on me);
- addme = should I be added to the tree? (for the --onlydeps mode)"""
- #stuff to add:
- #SLOT-aware emerge
- #IUSE-aware emerge
- #"no downgrade" emerge
- #print "mybigkey:",mybigkey
-
- jbigkey=string.join(mybigkey)
- if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"):
- #this conditional is needed to prevent infinite recursion on already-processed deps
- return 1
-
- update_spinner()
-
- mytype,myroot,mykey=mybigkey
- # select the correct /var database that we'll be checking against
- vardbapi=portage.db[myroot]["vartree"].dbapi
-
- # if the package is already on the system, we add a "nomerge"
- # directive, otherwise we add a "merge" directive.
- if mytype=="blocks":
- # we've encountered a "blocks" node. We will totally ignore this
- # node and not add it to our digraph if it doesn't apply to us.
- if addme and "--buildpkgonly" not in myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)):
- mybigkey.append(myparent.split()[2])
- self.digraph.addnode(string.join(mybigkey),myparent)
- return 1
-
- if myuse is None:
- self.pkgsettings.setcpv(mykey)
- myuse = self.pkgsettings["USE"].split()
- self.applied_useflags[mykey] = myuse
-
- merging=1
- if addme:
- # this is where we add the node to the list of packages to merge
- if not myparent:
- # command-line specified or part of a world list...
- if ("self" not in myparams) or (("selective" in myparams) and vardbapi.cpv_exists(mykey)):
- # the package is on the system, so don't merge it.
- merging=0
- elif ("selective" in myparams) and vardbapi.cpv_exists(mykey):
- merging=0
-
- if (merging==0 and "--newuse" in myopts and vardbapi.cpv_exists(mykey)):
- old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
- if mytype == "binary":
- iuses = portage.db["/"]["bintree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
- else:
- iuses = portage.db["/"]["porttree"].dbapi.aux_get(mykey, ["IUSE"])[0].split()
- for x in iuses:
- if (old_use.count(x) and not myuse.count(x)) or (not old_use.count(x) and myuse.count(x)):
- merging=1
- break
- else:
- #onlydeps mode; don't merge
- merging=2
- if merging==1:
- mybigkey.append("merge")
- else:
- mybigkey.append("nomerge")
-
- # whatever the case, we need to add the node to our digraph so
- # that children can depend upon it.
- self.digraph.addnode(string.join(mybigkey),myparent)
- if ("deep" not in myparams) and (not merging):
- return 1
- elif "recurse" not in myparams:
- return 1
-
- edepend={}
- if mytype=="binary":
- mypkgparts=portage.catpkgsplit(mykey)
- tbz2name = string.split(mykey, "/")[1]+".tbz2"
- if tbz2name in portage.db[portage.root]["bintree"].invalids:
- sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n")
- sys.exit(1)
- if portage.db[portage.root]["bintree"].isremote(mykey):
- edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name]
- edepend["DEPEND"] =""
- edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ")
- edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ")
- edepend["SLOT"] =string.strip(edepend["SLOT"])
- #portage.db[portage.root]["bintree"].gettbz2(mykey)
- else: # It's local.
- mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey))
- edepend["DEPEND"] =""
- edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ")
- edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ")
- edepend["SLOT"] =mytbz2.getfile("SLOT",mypkgparts[2])
- elif mytype=="ebuild":
- try:
- mymeta = ["DEPEND","RDEPEND","PDEPEND"]
- myfoo = portage.portdb.aux_get(mykey, mymeta)
- for index in range(0,len(mymeta)):
- edepend[mymeta[index]] = myfoo[index]
- if "--buildpkgonly" in myopts:
- edepend["RDEPEND"] = ""
- edepend["PDEPEND"] = ""
- except (KeyError,IOError):
- print "emerge: create(): aux_get() error on",mykey+"; aborting..."
- sys.exit(1)
- mydep={}
- mp=string.join(mybigkey)
-
- try:
- if myroot=="/":
- mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
- if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
- return 0
- else:
- mydep["/"]=edepend["DEPEND"]
- mydep[myroot]=edepend["RDEPEND"]
- if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
- return 0
- if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
- return 0
-
- if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
- # Post Depend -- Add to the list without a parent, as it depends
- # on a package being present AND must be built after that package.
- if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
- return 0
- except ValueError, e:
- pkgs = e.args[0]
- portage.writemsg("\n\n!!! An atom in the dependencies " + \
- "is not fully-qualified. Multiple matches:\n\n", noiselevel=-1)
- for cpv in pkgs:
- portage.writemsg(" %s\n" % cpv, noiselevel=-1)
- portage.writemsg("\n", noiselevel=-1)
- if mytype == "binary":
- portage.writemsg(
- "!!! This binary package cannot be installed: '%s'\n" % \
- mykey, noiselevel=-1)
- elif mytype == "ebuild":
- myebuild, mylocation = portage.portdb.findname2(mykey)
- portage.writemsg("!!! This ebuild cannot be installed: " + \
- "'%s'\n" % myebuild, noiselevel=-1)
- portage.writemsg("!!! Please notify the package maintainer " + \
- "that atoms must be fully-qualified.\n", noiselevel=-1)
- return 0
-
- return 1
-
- def select_files(self,myfiles):
- "given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
- myfavorites=[]
- for x in myfiles:
- ext = os.path.splitext(x)[1]
- if ext==".tbz2":
- if not os.path.exists(x):
- if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x):
- x=self.pkgsettings["PKGDIR"]+"/All/"+x
- elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x):
- x=self.pkgsettings["PKGDIR"]+"/"+x
- else:
- print "\n\n!!! Binary package '"+str(x)+"' does not exist."
- print "!!! Please ensure the tbz2 exists as specified.\n"
- sys.exit(1)
- mytbz2=xpak.tbz2(x)
- mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
- if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x):
- print red("\n*** You need to adjust PKGDIR to emerge this package.\n")
- sys.exit(1)
- if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in myopts):
- return (0,myfavorites)
- elif not "--oneshot" in myopts:
- myfavorites.append(mykey)
- elif ext==".ebuild":
- x = os.path.realpath(x)
- mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.splitext(os.path.basename(x))[0]
- ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey)
- if ebuild_path:
- if os.path.realpath(ebuild_path) != x:
- print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
- sys.exit(1)
- if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)):
- print red("\n*** You are emerging a masked package. It is MUCH better to use")
- print red("*** /etc/portage/package.* to accomplish this. See portage(5) man")
- print red("*** page for details.")
- countdown(EMERGE_WARNING_DELAY, "Continuing...")
- else:
- raise portage_exception.PackageNotFound(
- "%s is not in a valid portage tree hierarchy or does not exist" % x)
- if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in myopts):
- return (0,myfavorites)
- elif not "--oneshot" in myopts:
- myfavorites.append(mykey)
- else:
- if not is_valid_package_atom(x):
- portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x,
- noiselevel=-1)
- portage.writemsg("!!! Please check ebuild(5) for full details.\n")
- portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
- return (0,[])
- try:
- mykey=portage.dep_expand(x,mydb=portage.portdb)
- except ValueError, errpkgs:
- print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify"
- print "!!! one of the following fully-qualified ebuild names instead:\n"
- for i in errpkgs[0]:
- print " " + green(i)
- print
- sys.exit(1)
-
- # select needs to return 0 on dep_check failure
-
- sys.stdout.flush()
- sys.stderr.flush()
-
- try:
- self.mysd = self.select_dep(portage.root,mykey,arg=x)
- except portage_exception.MissingSignature, e:
- portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
- portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
- portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
- portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
- portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
- sys.exit(1)
- except portage_exception.InvalidSignature, e:
- portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
- portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
- portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
- portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
- portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
- sys.exit(1)
- except SystemExit, e:
- raise # Needed else can't exit
- except Exception, e:
- if "--debug" in myopts:
- raise
- print "\n\n!!! Problem in",mykey,"dependencies."
- print "!!!",str(e),e.__module__
- sys.exit(1)
-
- if not self.mysd:
- return (0,myfavorites)
- elif not "--oneshot" in myopts:
- myfavorites.append(portage.dep_getkey(mykey))
-
- missing=0
- if "--usepkgonly" in myopts:
- for x in self.digraph.dict.keys():
- xs=string.split(x," ")
- if (xs[0] != "binary") and (xs[3]=="merge"):
- if missing == 0:
- print
- missing += 1
- print "Missing binary for:",xs[2]
-
- # We're true here unless we are missing binaries.
- return (not missing,myfavorites)
-
- def is_newer_ver_installed(self,myroot,pkg,pkgver):
- "if there is a version of pkg installed newer than pkgver, return it"
- vardbapi=portage.db[myroot]["vartree"].dbapi
-
- matches=portage.db[myroot]["vartree"].dbapi.match(pkg)
- if matches:
- myslot=portage.db["/"]["porttree"].getslot(pkgver)
- for match in matches:
- if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0:
- curslot=portage.db[myroot]["vartree"].getslot(match)
- if curslot == myslot:
- return match
-
- def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False):
- "given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure"
- if "--debug" in myopts:
- print
- print "Parent: ",myparent
- print "Depstring:",depstring
- if not arg:
- #processing dependencies
- mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkgonly" in myopts),myroot=myroot)
-
- if not mycheck[0]:
- mymerge=[]
- else:
- mymerge=mycheck[1]
-
- else:
- #we're processing a command-line argument; unconditionally merge it even if it's already merged
- mymerge=[depstring]
-
- # dep_check has been run so we can now add our parent to our
- # build state to update virtuals and other settings. This
- # happens after the package is added to the tree so that a
- # package can depend on a virtual which it satisfies.
- if myparent:
- myp = myparent.split()
- if myp[3]=="merge":
- self.mydbapi[myroot].cpv_inject(myp[2])
- if myp[0]=="binary":
- self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi)
- else:
- self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi)
-
- if not mymerge:
- return 1
-
- if "--debug" in myopts:
- print "Candidates:",mymerge
- for x in mymerge:
- myk=None
- binpkguseflags=None
- if x[0]=="!":
- # if this package is myself, don't append it to block list.
- if "--debug" in myopts:
- print "Myparent",myparent
- if (myparent):
- if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]):
- # myself, so exit.
- continue
- # adding block
- myk=["blocks",myroot,x[1:]]
- else:
- #We are not processing a blocker but a normal dependency
- myeb=None
- myeb_matches = portage.portdb.xmatch("match-visible",x)
- if ("--usepkgonly" not in myopts):
- myeb=portage.best(myeb_matches)
-
- myeb_pkg=None
- if ("--usepkg" in myopts):
- # The next line assumes the binarytree has been populated.
- # XXX: Need to work out how we use the binary tree with roots.
- myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x)
- if ("--usepkgonly" not in myopts):
- # Remove any binary package entries that are masked in the portage tree (#55871)
- for idx in range(len(myeb_pkg_matches)-1,-1,-1):
- if myeb_pkg_matches[idx] not in myeb_matches:
- del myeb_pkg_matches[idx]
- myeb_pkg = portage.best(myeb_pkg_matches)
-
- if not myeb_pkg:
- myeb_pkg = None
- elif ("--newuse" in myopts):
- iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0])
- old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0])
- self.pkgsettings.setcpv(myeb_pkg)
- now_use=string.split(self.pkgsettings["USE"])
- for x in iuses:
- if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
- myeb_pkg = None
- break
-
- if (not myeb) and (not myeb_pkg):
- if raise_on_missing:
- raise ValueError
- if not arg:
- xinfo='"'+x+'"'
- else:
- xinfo='"'+arg+'"'
- if myparent:
- xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')'
- alleb=portage.portdb.xmatch("match-all",x)
- if alleb:
- if "--usepkgonly" not in myopts:
- print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
- print "!!! One of the following masked packages is required to complete your request:"
- oldcomment = ""
- for p in alleb:
- mreasons = portage.getmaskingstatus(p)
- print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")"
- comment = portage.getmaskingreason(p)
- if comment and comment != oldcomment:
- print comment
- oldcomment = comment
- print
- print "For more information, see MASKED PACKAGES section in the emerge man page or "
- print "refer to the Gentoo Handbook."
- else:
- print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
- print "!!! Either add a suitable binary package or compile from an ebuild."
- else:
- print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
- if myparent:
- print xfrom
- print
- return 0
-
- if "--debug" in myopts:
- print "ebuild:",myeb
- print "binpkg:",myeb_pkg
-
- if myeb and myeb_pkg:
- myeb_s = portage.catpkgsplit(myeb)
- myeb_s = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]]
- myeb_pkg_s = portage.catpkgsplit(myeb_pkg)
- myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]]
-
- if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild
- myeb = None
- else:
- myeb_pkg = None
-
- if myeb:
- myk=["ebuild",myroot,myeb]
- elif myeb_pkg:
- binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg)
- myk=["binary",myroot,myeb_pkg]
- else:
- sys.stderr.write("!!! Confused... Don't know what's being used for dependency info. :(\n")
- sys.exit(1)
-
- #if "--usepkg" in myopts:
- # #If we want to use packages, see if we have a pre-built one...
- # mypk=portage.db["/"]["bintree"].dbapi.match(x)
- # if myeb in mypk:
- # #Use it only if it's exactly the version we want.
- # myk=["binary",myroot,myeb]
- # else:
- # myk=["ebuild",myroot,myeb]
- #else:
- # myk=["ebuild",myroot,myeb]
- if myparent:
- #we are a dependency, so we want to be unconditionally added
- if not self.create(myk,myparent,myuse=binpkguseflags):
- return 0
- else:
- #if mysource is not set, then we are a command-line dependency and should not be added
- #if --onlydeps is specified.
- if not self.create(myk,myparent,"--onlydeps" not in myopts,myuse=binpkguseflags):
- return 0
-
- if "--debug" in myopts:
- print "Exiting...",myparent
- return 1
-
-
- def altlist(self):
- mygraph=self.digraph.copy()
- dolist=["/"]
- retlist=[]
- for x in portage.db.keys():
- portage.db[x]["merge"]=[]
- if x not in dolist:
- dolist.append(x)
- while (not mygraph.empty()):
- mycurkey=mygraph.firstzero()
- if not mycurkey:
- print "!!! Error: circular dependencies:"
- print
- for x in mygraph.dict.keys():
- for y in mygraph.dict[x][1]:
- print y,"depends on",x
- print
- sys.exit(1)
- splitski=string.split(mycurkey)
- #I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
- #These lines remove already-merged things from our alt-list
- #if "--update" in myopts:
- # if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
- # portage.db["/"]["merge"].append(splitski)
- #else:
- portage.db[splitski[1]]["merge"].append(splitski)
- mygraph.delnode(mycurkey)
- for x in dolist:
- for y in portage.db[x]["merge"]:
- retlist.append(y)
- return retlist
-
- def xcreate(self,mode="system"):
- global syslist
- world_problems = False
- if mode=="system":
- mylist=syslist
- else:
- #world mode
- worldlist=getlist("world")
- sysdict=genericdict(syslist)
- worlddict=genericdict(worldlist)
-
- for x in worlddict.keys():
- if not portage.isvalidatom(x):
- world_problems = True
- elif not portage.db["/"]["vartree"].dbapi.match(x):
- world_problems = True
- else:
- sysdict[x]=worlddict[x]
-
- mylist = sysdict.keys()
-
- newlist = []
- for atom in mylist:
- if portage.dep_getkey(atom).split("/")[-1] == "portage":
- newlist.insert(0, atom)
- else:
- newlist.append(atom)
- mylist = newlist
-
- missing_atoms = []
- for mydep in mylist:
- try:
- if not self.select_dep(portage.root, mydep, raise_on_missing=True):
- print "\n\n!!! Problem resolving dependencies for", mydep
- return 0
- except ValueError:
- missing_atoms.append(mydep)
-
- if world_problems:
- print "\n!!! Problems have been detected with your world file"
- print "!!! Please run "+green("emaint --check world")+"\n"
-
- if missing_atoms and "--verbose" in myopts:
- print "\n!!! Packages for the following atoms are either all"
- print "!!! masked or don't exist:"
- print " ".join(missing_atoms) + "\n"
-
- return 1
-
- def match(self,mydep,myroot=portage.root,mykey=None):
- # support mutual exclusive deps
- mydep2=mydep
- if mydep2[0]=="!":
- mydep2=mydep[1:]
-
- if mydep[0]=="!":
- #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example)
- myk="blocks "+myroot+" "+mydep2
- else:
- myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2)
- if not myeb:
- if not mykey:
- print "\n!!! Error: couldn't find match for",mydep
- else:
- print "\n!!! Error: couldn't find match for",mydep,"in",mykey
- print
- sys.exit(1)
-
- if "--usepkg" in myopts:
- mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
- if myeb==mypk:
- myk="binary "+portage.root+" "+mypk
- else:
- myk="ebuild "+myroot+" "+myeb
- else:
- myk="ebuild "+myroot+" "+myeb
-
- return myk
-
- def display(self,mylist,verbosity=("--quiet" in myopts and 1 or "--verbose" in myopts and 3 or 2 )):
- changelogs=[]
- p=[]
- totalsize=0
-
- if verbosity == 1:
- def create_use_string(*args):
- return ""
- else:
- def create_use_string(name, cur_iuse, cur_use, old_iuse, old_use, is_new,
- all_flags=(verbosity == 3), alphabetical=("--alphabetical" in myopts)):
- enabled = []
- if alphabetical:
- disabled = enabled
- else:
- disabled = []
- for flag in cur_iuse:
- if flag in cur_use:
- if is_new or flag in old_use and all_flags:
- enabled.append(red(flag))
- elif flag not in old_iuse:
- enabled.append(yellow(flag)+"%")
- elif flag not in old_use:
- enabled.append(green(flag)+"*")
- else:
- if is_new or flag in old_iuse and flag not in old_use and all_flags:
- disabled.append(blue("-"+flag))
- elif flag not in old_iuse:
- disabled.append(yellow("-"+flag)+"%")
- elif flag in old_use:
- disabled.append(green("-"+flag)+"*")
-
- enabled = " ".join(enabled)
- if alphabetical:
- disabled = ""
- else:
- disabled = " ".join(disabled)
- if enabled and disabled:
- ret = enabled + " " + disabled
- elif enabled:
- ret = enabled
- else:
- ret = disabled
- if ret:
- ret = '%s="%s" ' % (name, ret)
- return ret
-
- if verbosity == 3:
- overlays = self.pkgsettings["PORTDIR_OVERLAY"].split()
- overlays_real = [os.path.realpath(t) \
- for t in self.pkgsettings["PORTDIR_OVERLAY"].split()]
-
- if "--tree" in myopts:
- mylist.reverse()
- mygraph=self.digraph.copy()
-
- i = 0
- while i < len(mylist):
- if mylist[i][-1]=="nomerge":
- if not ("--tree" in myopts):
- # we don't care about this elements
- mylist.pop(i)
- continue
- if (i == (len(mylist) - 1)) \
- or (mygraph.depth(string.join(mylist[i])) \
- >= mygraph.depth(string.join(mylist[i+1]))):
- # end of a useless branch (may be the last one)
- # -> delete the element and test the previous one
- mylist.pop(i)
- if i > 0:
- i -= 1
- continue
- # the branch continues, or we've found a good element.
- # -> let's see what's next, if anything
- i += 1
-
- display_overlays=False
- # files to fetch list - avoids counting a same file twice
- # in size display (verbose mode)
- myfetchlist=[]
- for x in mylist:
- pkg_type = x[0]
- pkg_key = x[2]
- if pkg_key not in self.applied_useflags:
- if "binary" == pkg_type:
- self.applied_useflags[pkg_key] = portage.db["/"]["bintree"].dbapi.aux_get(pkg_key, ["USE"])[0].split()
- elif "ebuild" == pkg_type:
- self.pkgsettings.setcpv(pkg_key)
- self.applied_useflags[pkg_key] = self.pkgsettings["USE"].split()
-
- fetch=" "
-
- if x[0]=="blocks":
- addl=""+red("B")+" "+fetch+" "
- resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
- print "["+x[0]+" "+addl+"]",red(resolved),
- if resolved!=x[2]:
- if x[3]:
- print red("(\""+x[2]+"\" is blocking "+x[3]+")")
- else:
- print red("(\""+x[2]+"\")")
- else:
- if x[3]:
- print red("(is blocking "+x[3]+")")
- else:
- print
- else:
- if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
- fetch = red("F")
- if portage.portdb.fetch_check(x[2], self.applied_useflags[x[2]]):
- fetch = green("f")
-
- #we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
- #param is used for -u, where you still *do* want to see when something is being upgraded.
- myoldbest=""
- if (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]):
- addl=" "+yellow("R")+fetch+" "
- elif (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]):
- if x[0] == "binary":
- mynewslot=portage.db["/"]["bintree"].getslot(x[2])
- elif x[0] == "ebuild":
- mynewslot=portage.db["/"]["porttree"].getslot(x[2])
- myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])
- myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist)
- if myinslotlist:
- myoldbest=portage.best(myinslotlist)
- addl=" "+fetch
- if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
- # Downgrade in slot
- addl+=turquoise("U")+blue("D")
- else:
- # Update in slot
- addl+=turquoise("U")+" "
- else:
- # New slot, mark it new.
- addl=" "+green("NS")+fetch+" "
-
- if "--changelog" in myopts:
- changelogs.extend(self.calc_changelog(
- portage.portdb.findname(x[2]),
- portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])),
- x[2]
- ))
- else:
- addl=" "+green("N")+" "+fetch+" "
-
- verboseadd=""
-
- if x[2] in self.applied_useflags:
- # USE flag display
- if x[0] == "binary":
- cur_iuse = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0])
- elif x[0] == "ebuild":
- cur_iuse = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0])
- else:
- cur_iuse = []
-
- cur_iuse = portage.unique_array(cur_iuse)
- cur_iuse = [flag for flag in cur_iuse if flag not in portage.settings.usemask]
- cur_iuse.sort()
- cur_use = self.applied_useflags[x[2]]
- cur_use = [flag for flag in cur_use if flag in cur_iuse]
-
- if myoldbest:
- pkg = myoldbest
- else:
- pkg = x[2]
- if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg):
- (old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"])
- old_iuse = portage.unique_array(old_iuse.split())
- old_iuse.sort()
- old_use = old_use.split()
- is_new = False
- else:
- old_iuse = []
- old_use = []
- is_new = True
- old_iuse = [flag for flag in old_iuse if flag not in portage.settings.usemask]
- old_use = [flag for flag in old_use if flag in old_iuse]
-
- use_expand = portage.settings["USE_EXPAND"].lower().split()
- use_expand.sort()
- use_expand.reverse()
- use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].lower().split()
-
- def map_to_use_expand(myvals):
- ret = {}
- for exp in use_expand:
- ret[exp] = []
- for val in myvals[:]:
- if val.startswith(exp.lower()+"_"):
- ret[exp].append(val[len(exp)+1:])
- myvals.remove(val)
- ret["USE"] = myvals
- for exp in use_expand_hidden:
- if exp in ret:
- del ret[exp]
- return ret
-
- cur_iuse_map = map_to_use_expand(cur_iuse)
- cur_use_map = map_to_use_expand(cur_use)
- old_iuse_map = map_to_use_expand(old_iuse)
- old_use_map = map_to_use_expand(old_use)
-
- use_expand.sort()
- use_expand.insert(0, "USE")
-
- for key in use_expand:
- if key in use_expand_hidden:
- continue
- verboseadd += create_use_string(key.upper(), cur_iuse_map[key], cur_use_map[key],
- old_iuse_map[key], old_use_map[key], is_new)
-
- if verbosity == 3:
- # size verbose
- mysize=0
- if x[0] == "ebuild" and x[-1]!="nomerge":
- myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug)
- if myfilesdict is None:
- myfilesdict="[empty/missing/bad digest]"
- else:
- for myfetchfile in myfilesdict.keys():
- if myfetchfile not in myfetchlist:
- mysize+=myfilesdict[myfetchfile]
- myfetchlist.append(myfetchfile)
- totalsize+=mysize
- verboseadd+=format_size(mysize)+" "
-
- # overlay verbose
- # XXX: Invalid binaries have caused tracebacks here. 'if file_name'
- # x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge']
- file_name=portage.portdb.findname(x[2])
- if file_name: # It might not exist in the tree
- dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..")
- if (overlays_real.count(dir_name)>0):
- verboseadd+=teal("["+str(overlays_real.index(
- os.path.normpath(dir_name))+1)+"]")+" "
- display_overlays=True
- else:
- verboseadd += "[No ebuild?]"
-
- xs=portage.pkgsplit(x[2])
- if xs[2]=="r0":
- xs[2]=""
- else:
- xs[2]="-"+xs[2]
-
- if self.pkgsettings.has_key("COLUMNWIDTH"):
- mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"])
- else:
- mywidth=130
- oldlp=mywidth-30
- newlp=oldlp-30
-
- indent=""
- if ("--tree" in myopts):
- indent=" "*mygraph.depth(string.join(x))
-
- if myoldbest:
- myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
- if myoldbest[-3:]=="-r0":
- myoldbest=myoldbest[:-3]
- myoldbest=blue("["+myoldbest+"]")
-
- if x[1]!="/":
- if myoldbest:
- myoldbest +=" "
- if "--columns" in myopts:
- if "--quiet" in myopts:
- myprint=addl+" "+indent+darkgreen(xs[0])
- myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
- myprint=myprint+myoldbest
- myprint=myprint+darkgreen("to "+x[1])
- else:
- myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
- if (newlp-nc_len(myprint)) > 0:
- myprint=myprint+(" "*(newlp-nc_len(myprint)))
- myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
- if (oldlp-nc_len(myprint)) > 0:
- myprint=myprint+" "*(oldlp-nc_len(myprint))
- myprint=myprint+myoldbest
- myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
- else:
- myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+darkgreen("to "+x[1])+" "+verboseadd
- else:
- if "--columns" in myopts:
- if "--quiet" in myopts:
- myprint=addl+" "+indent+darkgreen(xs[0])
- myprint=myprint+" "+green(xs[1]+xs[2])+" "
- myprint=myprint+myoldbest
- else:
- myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
- if (newlp-nc_len(myprint)) > 0:
- myprint=myprint+(" "*(newlp-nc_len(myprint)))
- myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
- if (oldlp-nc_len(myprint)) > 0:
- myprint=myprint+(" "*(oldlp-nc_len(myprint)))
- myprint=myprint+myoldbest+" "+verboseadd
- else:
- if x[3]=="nomerge":
- myprint=darkblue("[nomerge ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd
- else:
- myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd
- p.append(myprint)
-
- mysplit = portage.pkgsplit(x[2])
- if "--tree" not in myopts and mysplit and len(mysplit) == 3 and \
- mysplit[0] == "sys-apps/portage" and x[1] == "/":
-
- if mysplit[2] == "r0":
- myversion = mysplit[1]
- else:
- myversion = "%s-%s" % (mysplit[1], mysplit[2])
-
- if myversion != portage.VERSION :
- if "--emptytree" in myopts:
- p.append(red("***")+" Please update portage to the above version before proceeding.")
- p.append(" Failure to do so may result in failed or improper merges.")
- p.append(" A simple '"+green("emerge portage")+"' is sufficient.")
- p.append("")
- elif mylist.index(x) < len(mylist) - 1 and \
- "livecvsportage" not in portage.settings.features:
- p.append(red("*** Portage will stop merging at this point and reload itself,"))
- p.append(red(" then resume the merge."))
- print
- del mysplit
-
- for x in p:
- print x
-
- if verbosity == 3:
- print
- print "Total size of downloads: "+format_size(totalsize)
- if overlays and display_overlays:
- print "Portage overlays:"
- y=0
- for x in overlays:
- y=y+1
- print " "+teal("["+str(y)+"]"),x
-
- if "--changelog" in myopts:
- print
- for revision,text in changelogs:
- print bold('*'+revision)
- sys.stdout.write(text)
-
- def calc_changelog(self,ebuildpath,current,next):
- current = '-'.join(portage.catpkgsplit(current)[1:])
- if current.endswith('-r0'): current = current[:-3]
- next = '-'.join(portage.catpkgsplit(next)[1:])
- if next.endswith('-r0'): next = next[:-3]
- changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
- try:
- changelog = open(changelogpath).read()
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- return []
- divisions = self.find_changelog_tags(changelog)
- #print 'XX from',current,'to',next
- #for div,text in divisions: print 'XX',div
- # skip entries for all revisions above the one we are about to emerge
- for i in range(len(divisions)):
- if divisions[i][0]==next:
- divisions = divisions[i:]
- break
- # find out how many entries we are going to display
- for i in range(len(divisions)):
- if divisions[i][0]==current:
- divisions = divisions[:i]
- break
- else:
- # couldnt find the current revision in the list. display nothing
- return []
- return divisions
-
- def find_changelog_tags(self,changelog):
- divs = []
- release = None
- while 1:
- match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M)
- if match is None:
- if release is not None:
- divs.append((release,changelog))
- return divs
- if release is not None:
- divs.append((release,changelog[:match.start()]))
- changelog = changelog[match.end():]
- release = match.group(1)
- if release.endswith('.ebuild'):
- release = release[:-7]
- if release.endswith('-r0'):
- release = release[:-3]
-
- def outdated(self):
- return self.outdatedpackages
-
- def merge(self,mylist):
- returnme=0
- mymergelist=[]
-
- #check for blocking dependencies
- if ("--fetchonly" not in myopts) and ("--buildpkgonly" not in myopts):
- for x in mylist:
- if x[0]=="blocks":
- print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
- print "!!! the two packages cannot be installed on the same system together."
- print "!!! Please use 'emerge --pretend' to determine blockers."
- print
- if ("--pretend" not in myopts):
- try:
- del portage.mtimedb["resume"]
- except KeyError:
- pass
- sys.exit(1)
-
- #buildsyspkg: I need mysysdict also on resume (moved from the else block)
- mysysdict=genericdict(syslist)
- if ("--resume" in myopts):
- # We're resuming.
- print green("*** Resuming merge...")
- emergelog(" *** Resuming merge...")
- mymergelist=portage.mtimedb["resume"]["mergelist"][:]
- if ("--skipfirst" in myopts) and mymergelist:
- del portage.mtimedb["resume"]["mergelist"][0]
- del mymergelist[0]
- validate_merge_list(mymergelist)
- else:
- myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE))
- myfavdict=genericdict(myfavs)
- for x in range(len(mylist)):
- if mylist[x][3]!="nomerge":
- # Add to the mergelist
- mymergelist.append(mylist[x])
- else:
- myfavkey=portage.cpv_getkey(mylist[x][2])
- if "--onlydeps" in myopts:
- continue
- # Add to the world file. Since we won't be able to later.
- if (not "--fetchonly" in myopts) and (myfavkey in favorites):
- #don't record if already in system profile or already recorded
- if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
- #we don't have a favorites entry for this package yet; add one
- myfavdict[myfavkey]=myfavkey
- print ">>> Recording",myfavkey,"in \"world\" favorites file..."
- if not "--fetchonly" in myopts:
- portage.write_atomic(
- os.path.join(portage.root, portage.WORLD_FILE),
- "\n".join(myfavdict.values()))
-
- portage.mtimedb["resume"]["mergelist"]=mymergelist[:]
-
- # We need to yank the harmful-to-new-builds settings from features.
- myorigfeat=self.pkgsettings["FEATURES"]
- myfeat=myorigfeat.split()
- while ("keeptemp" in myfeat):
- del myfeat[myfeat.index("keeptemp")]
- while ("keepwork" in myfeat):
- del myfeat[myfeat.index("keepwork")]
-
- self.pkgsettings["FEATURES"]=string.join(myfeat)
-
- if "parallel-fetch" in myfeat and not ("--ask" in myopts or "--pretend" in myopts or "--fetchonly" in myopts):
- if "distlocks" not in myfeat:
- print red("!!!")
- print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
- print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
- print red("!!!")
- elif len(mymergelist) > 1:
- print ">>> starting parallel fetching"
- pid = os.fork()
- if not pid:
- sys.stdin.close()
- sys.stdout.close()
- sys.stderr.close()
- time.sleep(3) # allow the parent to have first fetch
- fetchlog = "/var/log/emerge-fetch.log"
- sys.stdout = open(fetchlog, "w")
- sys.stderr = sys.stdout
- os.dup2(sys.stdout.fileno(), 1)
- os.dup2(sys.stderr.fileno(), 2)
- portage_util.apply_secpass_permissions(fetchlog,
- uid=portage.portage_uid, gid=portage.portage_gid,
- mode=0660)
-
- # wipe the mtimedb so that portage doesn't attempt to flush it.
- # do not convert this code away from a fork without correcting this.
- portage.mtimedb = None
- for x in ("autoaddcvs", "cvs"):
- try: myfeat.remove(x)
- except ValueError: pass
- self.pkgsettings["FEATURES"] = " ".join(myfeat)
- ret = 0
- for x in mymergelist:
- if x[0] != "ebuild":
- continue
- try:
- ret = portage.doebuild(portage.portdb.findname(x[2]), "fetch", x[1], self.pkgsettings,
- cleanup=0, fetchonly=True, tree="porttree")
- except SystemExit:
- raise
- except Exception:
- ret = 1
- sys.exit(0)
- portage.portage_exec.spawned_pids.append(pid)
-
- mergecount=0
- for x in mymergelist:
- mergecount+=1
- myroot=x[1]
- pkgindex=2
- if x[0]=="blocks":
- pkgindex=3
- y=portage.portdb.findname(x[pkgindex])
- if not "--pretend" in myopts:
- print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
- emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
-
- self.pkgsettings["EMERGE_FROM"] = x[0][:]
- self.pkgsettings.backup_changes("EMERGE_FROM")
- self.pkgsettings.reset()
-
- #buildsyspkg: Check if we need to _force_ binary package creation
- issyspkg = ("buildsyspkg" in myfeat) \
- and x[0] != "blocks" \
- and mysysdict.has_key(portage.cpv_getkey(x[2])) \
- and not ("--buildpkg" in myopts)
- if x[0] in ["ebuild","blocks"]:
- if (x[0]=="blocks") and ("--fetchonly" not in myopts):
- raise Exception, "Merging a blocker"
- elif ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
- if ("--fetch-all-uri" in myopts):
- retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,fetchall=1,tree="porttree")
- else:
- retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,tree="porttree")
- if (retval is None) or retval:
- print
- print "!!! Fetch for",y,"failed, continuing..."
- print
- returnme=1
- continue
- elif "--buildpkg" in myopts or issyspkg:
- #buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
- if issyspkg:
- print ">>> This is a system package, let's pack a rescue tarball."
- #emergelog(">>> This is a system package, let's pack a rescue tarball.")
- #create pkg, then merge pkg
- short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
- emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
- retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
- if (retval is None):
- portage_util.writemsg("Unable to run required binary.\n",
- noiselevel=-1)
- sys.exit(127)
- if retval:
- sys.exit(retval)
- short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
- emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
- retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug,tree="porttree")
- if (retval is None):
- portage_util.writemsg("Unable to run required binary.\n",
- noiselevel=-1)
- sys.exit(127)
- if retval:
- sys.exit(retval)
- #dynamically update our database
- if "--buildpkgonly" not in myopts:
- portage.db[portage.root]["bintree"].inject(x[2])
- mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
- short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
- emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
-
- self.pkgsettings["EMERGE_FROM"] = "binary"
- self.pkgsettings.backup_changes("EMERGE_FROM")
-
- retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings)
- if retval is None:
- sys.exit(1)
- elif "noclean" not in self.pkgsettings.features:
- portage.doebuild(y, "clean", myroot, self.pkgsettings,
- edebug, tree="porttree")
- else:
- short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
- emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
- retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree")
- if (retval is None):
- portage_util.writemsg("Unable to run required binary.\n",
- noiselevel=-1)
- sys.exit(127)
- if retval:
- sys.exit(retval)
- short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
- emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
- retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug,tree="porttree")
- if (retval is None):
- portage_util.writemsg("Unable to run required binary.\n",
- noiselevel=-1)
- sys.exit(127)
- if retval:
- sys.exit(retval)
- #dynamically update our database
- elif x[0]=="binary":
- #merge the tbz2
- mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
- if portage.db[portage.root]["bintree"].isremote(x[2]):
- short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
- emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
- if not portage.db[portage.root]["bintree"].gettbz2(x[2]):
- sys.exit(1)
-
- if ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
- continue
-
- short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
- emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
- retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings)
- if retval is None:
- sys.exit(1)
- #need to check for errors
- if "--buildpkgonly" not in myopts:
- portage.db[x[1]]["vartree"].inject(x[2])
- myfavkey=portage.cpv_getkey(x[2])
- if "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts and myfavkey in favorites:
- myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE))
- myfavdict=genericdict(myfavs)
- mysysdict=genericdict(syslist)
- #don't record if already in system profile or already recorded
- if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
- #we don't have a favorites entry for this package yet; add one
- myfavdict[myfavkey]=myfavkey
- print ">>> Recording",myfavkey,"in \"world\" favorites file..."
- emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")")
- portage.write_atomic(
- os.path.join(myroot, portage.WORLD_FILE),
- "\n".join(myfavdict.values()))
-
- if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
- # Clean the old package that we have merged over top of it.
- if self.pkgsettings["AUTOCLEAN"]=="yes":
- xsplit=portage.pkgsplit(x[2])
- emergelog(" >>> AUTOCLEAN: "+xsplit[0])
- if x[1] == portage.settings["ROOT"]:
- # Compare against portage.settings["ROOT"] because
- # the value of self.pkgsettings["ROOT"] does not
- # match the original value!
- retval = unmerge("clean", [xsplit[0]])
- else:
- retval = unmerge_overlapping(x[2], x[1],
- self.pkgsettings, portage.db[x[1]]["vartree"])
- if not retval:
- emergelog(" --- AUTOCLEAN: Nothing unmerged.")
- else:
- portage.writemsg_stdout(colorize("WARN", "WARNING:")
- + " AUTOCLEAN is disabled. This can cause serious"
- + " problems due to overlapping packages.\n")
-
- # Figure out if we need a restart.
- mysplit=portage.pkgsplit(x[2])
- if mysplit[0] == "sys-apps/portage" and x[1] == "/":
- myver=mysplit[1]+"-"+mysplit[2]
- if myver[-3:]=='-r0':
- myver=myver[:-3]
- if (myver != portage.VERSION) and \
- ("livecvsportage" not in portage.settings.features):
- if len(mymergelist) > mergecount:
- emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
- emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
- del portage.mtimedb["resume"]["mergelist"][0]
- portage.run_exitfuncs()
- mynewargv=[sys.argv[0],"--resume"]
- badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume")
- for arg in myopts:
- if arg in badlongopts:
- continue
- mynewargv.append(arg)
- # priority only needs to be adjusted on the first run
- os.environ["PORTAGE_NICENESS"] = "0"
- os.execv(mynewargv[0], mynewargv)
-
- if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
- if "noclean" not in portage.settings.features:
- short_msg = "emerge: (%s of %s) %s Clean Post" % \
- (mergecount, len(mymergelist), x[pkgindex])
- emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \
- (mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg)
- emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
-
- # Unsafe for parallel merges
- del portage.mtimedb["resume"]["mergelist"][0]
- # Commit after each merge so that --resume may still work in
- # in the event that portage is not allowed to exit normally
- # due to power failure, SIGKILL, etc...
- portage.commit_mtimedb()
-
- emergelog(" *** Finished. Cleaning up...")
-
- # We're out of the loop... We're done. Delete the resume data.
- if portage.mtimedb.has_key("resume"):
- del portage.mtimedb["resume"]
-
- if ("--pretend" not in myopts):
- if ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
- if (mergecount>0):
- if retval:
- portage.env_update()
-
- #by doing an exit this way, --fetchonly can continue to try to
- #fetch everything even if a particular download fails.
- if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
- if returnme:
- print "\n\n!!! Some fetch errors were encountered. Please see above for details.\n\n"
- sys.exit(returnme)
- else:
- sys.exit(0)
-
- def unmerge_overlapping(pkg_key, myroot, mysettings, vartree):
- """Unmerge any packages that overlap with the given package (overlapping
- packages fill the same SLOT). Unlike emerge's unmerge() function, this
- function does not assume that packages are to be unmerged from the target
- ROOT. This function is only needed in the case where ROOT!=/ and the
- previous version of a build time dependency (that has been upgraded) needs
- to be cleaned from / (instead of the target ROOT). When the incorrect
- assumptions in unmerge() have been fixed, this function can be removed."""
-
- overlapping = []
- ommitted_versions = []
- mydbapi = vartree.dbapi
- myslot = mydbapi.aux_get(pkg_key, ["SLOT"])[0]
- mycp = portage.pkgsplit(pkg_key)[0]
- for other_pkg in mydbapi.cp_list(mycp):
- if other_pkg == pkg_key:
- continue
- other_slot = mydbapi.aux_get(other_pkg, ["SLOT"])[0]
- if myslot == other_slot:
- overlapping.append(other_pkg)
- else:
- ommitted_versions.append(other_pkg)
- if overlapping:
- def get_version(pkg_key):
- cp, pv, rev = portage.pkgsplit(pkg_key)
- if rev == "r0":
- return pv
- else:
- return "%s-%s" % (pv, rev)
- selected_versions = ",".join(map(get_version, overlapping))
- protected_version = get_version(pkg_key)
- if ommitted_versions:
- ommitted_versions = ",".join(map(get_version, ommitted_versions))
- else:
- ommitted_versions = "none"
- portage.writemsg_stdout("\n %s\n" % bold(mycp), noiselevel=-1)
- portage.writemsg_stdout("selected: ".rjust(14) + selected_versions + \
- "\n", noiselevel=-1)
- portage.writemsg_stdout("protected: ".rjust(14) + protected_version + \
- "\n", noiselevel=-1)
- portage.writemsg_stdout("omitted: ".rjust(14) + ommitted_versions + \
- "\n", noiselevel=-1)
- portage.writemsg_stdout("\n>>>" + red("'Selected'") + \
- " packages are slated for removal.\n", noiselevel=0)
- portage.writemsg_stdout(">>>" + green("'Protected'") + " and " + \
- green("'omitted'") + " packages will not be removed.\n\n",
- noiselevel=0)
- global CLEAN_DELAY
- countdown(CLEAN_DELAY, ">>> Unmerging")
- for other_pkg in overlapping:
- portage.writemsg_stdout(">>> Unmerging %s...\n" % other_pkg ,
- noiselevel=-1)
- emergelog("=== Unmerging... (%s)" % other_pkg)
- mysplit = other_pkg.split("/")
- retval = portage.unmerge(mysplit[0], mysplit[1], myroot,
- mysettings, mytrimworld=False, vartree=vartree)
- if retval:
- emergelog(" !!! unmerge FAILURE: " + other_pkg)
- else:
- emergelog(" >>> unmerge success: " + other_pkg)
- return 1
- return 0
-
- def unmerge(unmerge_action, unmerge_files, raise_on_missing=True):
- candidate_catpkgs=[]
- global_unmerge=0
-
- realsyslist = getlist("system")
- syslist = []
- for x in realsyslist:
- mycp = portage.dep_getkey(x)
- if mycp in portage.settings.getvirtuals():
- providers = []
- for provider in portage.settings.getvirtuals()[mycp]:
- if portage.db[portage.root]["vartree"].dbapi.match(provider):
- providers.append(provider)
- if len(providers) == 1:
- syslist.extend(providers)
- else:
- syslist.append(mycp)
-
- global myopts
- mysettings = portage.config(clone=portage.settings)
-
- if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files:
- if "unmerge"==unmerge_action:
- print
- print bold("emerge unmerge")+" can only be used with specific package names, not with "+bold("world")+" or"
- print bold("system")+" targets."
- print
- return 0
- else:
- global_unmerge=1
-
- localtree=portage.db[portage.root]["vartree"]
- # process all arguments and add all valid db entries to candidate_catpkgs
- if global_unmerge:
- if not unmerge_files or "world" in unmerge_files:
- candidate_catpkgs.extend(localtree.getallnodes())
- elif "system" in unmerge_files:
- candidate_catpkgs.extend(getlist("system"))
- else:
- #we've got command-line arguments
- if not unmerge_files:
- print "\nNo packages to unmerge have been provided.\n"
- return 0
- for x in unmerge_files:
- arg_parts=x.split('/')
- if (x[0] not in [".","/"]) and (arg_parts[-1][-7:] != ".ebuild"):
- #possible cat/pkg or dep; treat as such
- candidate_catpkgs.append(x)
- elif unmerge_action in ["prune","clean"]:
- print "\n!!! Prune and clean do not accept individual ebuilds as arguments;\n skipping.\n"
- continue
- else:
- # it appears that the user is specifying an installed ebuild and we're in "unmerge" mode, so it's
- # ok.
- if not os.path.exists(x):
- print "\n!!! The path '"+x+"' doesn't exist.\n"
- return 0
-
- absx = os.path.abspath(x)
- sp_absx = absx.split("/")
- if sp_absx[-1][-7:] == ".ebuild":
- del sp_absx[-1]
- absx = string.join(sp_absx,"/")
-
- sp_absx_len = len(sp_absx)
-
- vdb_path = portage.root+portage.VDB_PATH
- vdb_len = len(vdb_path)
-
- sp_vdb = vdb_path.split("/")
- sp_vdb_len = len(sp_vdb)
-
- if not os.path.exists(absx+"/CONTENTS"):
- print "!!! Not a valid db dir: "+str(absx)
- return 0
-
- if sp_absx_len <= sp_vdb_len:
- # The Path is shorter... so it can't be inside the vdb.
- print spabsx
- print absx
- print "\n!!!",x,"cannot be inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
- return 0
-
- for idx in range(0,sp_vdb_len):
- if (idx >= sp_absx_len) or (sp_vdb[idx] != sp_absx[idx]):
- print sp_absx
- print absx
- print "\n!!!",x,"is not inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
- return 0
-
- print "="+string.join(sp_absx[sp_vdb_len:],"/")
- candidate_catpkgs.append("="+string.join(sp_absx[sp_vdb_len:],"/"))
-
- newline=""
- if (not "--quiet" in myopts):
- newline="\n"
- if portage.settings["ROOT"] != "/":
- print darkgreen(newline+">>> Using system located in ROOT tree "+portage.settings["ROOT"])
- if (("--pretend" in myopts) or ("--ask" in myopts)) and not ("--quiet" in myopts):
- print darkgreen(newline+">>> These are the packages that would be unmerged:")
-
- pkgmap={}
- numselected=0
- for x in candidate_catpkgs:
- #cycle through all our candidate deps and determine what will and will not get unmerged
- try:
- mymatch=localtree.dep_match(x)
- except KeyError:
- mymatch=None
- except ValueError, errpkgs:
- print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify"
- print "!!! one of the following fully-qualified ebuild names instead:\n"
- for i in errpkgs[0]:
- print " " + green(i)
- print
- sys.exit(1)
-
- if not mymatch and x[0] not in "<>=~":
- #add a "=" if missing
- mymatch=localtree.dep_match("="+x)
- if not mymatch:
- if raise_on_missing:
- raise portage_exception.PackageNotFound(x)
- else:
- portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \
- (x, unmerge_action), noiselevel=-1)
- continue
- mykey=portage.key_expand(portage.dep_getkey(mymatch[0]),portage.db["/"]["vartree"].dbapi)
- if not pkgmap.has_key(mykey):
- pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] }
- if unmerge_action=="unmerge":
- for y in mymatch:
- if y not in pkgmap[mykey]["selected"]:
- pkgmap[mykey]["selected"].append(y)
- numselected=numselected+len(mymatch)
-
- else:
- #unmerge_action in ["prune", clean"]
- slotmap={}
- for mypkg in mymatch:
- if unmerge_action=="clean":
- myslot=localtree.getslot(mypkg)
- else:
- #since we're pruning, we don't care about slots and put all the pkgs in together
- myslot=0
- if not slotmap.has_key(myslot):
- slotmap[myslot]={}
- slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)]=mypkg
- for myslot in slotmap.keys():
- counterkeys=slotmap[myslot].keys()
- counterkeys.sort()
- if not counterkeys:
- continue
- counterkeys.sort()
- pkgmap[mykey]["protected"].append(slotmap[myslot][counterkeys[-1]])
- del counterkeys[-1]
- #be pretty and get them in order of merge:
- for ckey in counterkeys:
- pkgmap[mykey]["selected"].append(slotmap[myslot][ckey])
- numselected=numselected+1
- #ok, now the last-merged package is protected, and the rest are selected
- if global_unmerge and not numselected:
- print "\n>>> No outdated packages were found on your system.\n"
- return 0
-
- if not numselected:
- print "\n>>> No packages selected for removal by",unmerge_action+".\n"
- return 0
-
- for x in pkgmap.keys():
- for y in localtree.dep_match(x):
- if y not in pkgmap[x]["omitted"] and \
- y not in pkgmap[x]["selected"] and \
- y not in pkgmap[x]["protected"]:
- pkgmap[x]["omitted"].append(y)
- if global_unmerge and not pkgmap[x]["selected"]:
- #avoid cluttering the preview printout with stuff that isn't getting unmerged
- continue
- if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and (x in syslist):
- print red("\a\n\n!!! '%s' is part of your system profile." % x)
- print yellow("\a!!! Unmerging it may be damaging to your system.\n")
- if "--pretend" not in myopts and "--ask" not in myopts:
- global EMERGE_WARNING_DELAY
- countdown(EMERGE_WARNING_DELAY,red("Press Ctrl-C to Stop"))
- print "\n "+white(x)
- for mytype in ["selected","protected","omitted"]:
- print string.rjust(mytype,12)+":",
- if pkgmap[x][mytype]:
- for mypkg in pkgmap[x][mytype]:
- mysplit=portage.catpkgsplit(mypkg)
- if mysplit[3]=="r0":
- myversion=mysplit[2]
- else:
- myversion=mysplit[2]+"-"+mysplit[3]
- if mytype=="selected":
- print red(myversion),
- else:
- print green(myversion),
- else:
- print "none",
- print
-
- if (not "--quiet" in myopts):
- print "\n>>>",red("'Selected'"),"packages are slated for removal."
- print ">>>",green("'Protected'"),"and",green("'omitted'"),"packages will not be removed.\n"
-
- if "--pretend" in myopts:
- #we're done... return
- return 0
- if "--ask" in myopts:
- if userquery("Would you like to unmerge these packages?")=="No":
- # enter pretend mode for correct formatting of results
- myopts+=["--pretend"]
- print
- print "Quitting."
- print
- return 0
- #the real unmerging begins, after a short delay....
-
- global CLEAN_DELAY
- countdown(CLEAN_DELAY, ">>> Unmerging")
-
- for x in pkgmap.keys():
- for y in pkgmap[x]["selected"]:
- print ">>> Unmerging "+y+"..."
- emergelog("=== Unmerging... ("+y+")")
- mysplit=string.split(y,"/")
- #unmerge...
- retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,mysettings,unmerge_action not in ["clean","prune"])
- if retval:
- emergelog(" !!! unmerge FAILURE: "+y)
- else:
- emergelog(" >>> unmerge success: "+y)
- #run ldconfig, etc...
- portage.env_update()
- if not numselected:
- return 0
- else:
- return 1
-
-
- def chk_updated_info_files(retval):
- root=portage.root
-
- infodirs=[]
- infodirs.extend(string.split(portage.settings["INFOPATH"], ":"))
- infodirs.extend(string.split(portage.settings["INFODIR"], ":"))
-
- print
- if os.path.exists("/usr/bin/install-info"):
- regen_infodirs=[]
- for z in infodirs:
- if z=='':
- continue
- inforoot=normpath(root+z)
- if os.path.isdir(inforoot):
- try:
- infomtime=os.stat(inforoot)[ST_MTIME]
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- infomtime=0
-
- if not portage.mtimedb.has_key("info"):
- portage.mtimedb["info"]={}
- if portage.mtimedb["info"].has_key(inforoot):
- if portage.mtimedb["info"][inforoot]==infomtime:
- pass
- else:
- portage.mtimedb["info"][inforoot]=infomtime
- regen_infodirs.append(inforoot)
- else:
- regen_infodirs.append(inforoot)
-
- if not regen_infodirs:
- print " "+green("*")+" GNU info directory index is up-to-date."
- else:
- print " "+green("*")+" Regenerating GNU info directory index..."
-
- icount=0
- badcount=0
- for inforoot in regen_infodirs:
- if inforoot=='':
- continue
- try:
- os.rename(inforoot+"/dir",inforoot+"/dir.old")
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- pass
-
- if not os.path.isdir(inforoot):
- continue
- errmsg = ""
- for x in os.listdir(inforoot):
- if (x[0] == ".") or (x in ["dir","dir.old"]) or (os.path.isdir(inforoot+"/"+x)):
- continue
- myso=commands.getstatusoutput("LANG=C LANGUAGE=C /usr/bin/install-info --dir-file="+inforoot+"/dir "+inforoot+"/"+x)[1]
- existsstr="already exists, for file `"
- if myso!="":
- if re.search(existsstr,myso):
- # Already exists... Don't increment the count for this.
- pass
- elif myso[:44]=="install-info: warning: no info dir entry in ":
- # This info file doesn't contain a DIR-header: install-info produces this
- # (harmless) warning (the --quiet switch doesn't seem to work).
- # Don't increment the count for this.
- pass
- else:
- badcount=badcount+1
- errmsg += myso + "\n"
- icount=icount+1
-
- #update mtime so we can potentially avoid regenerating.
- portage.mtimedb["info"][inforoot]=os.stat(inforoot)[ST_MTIME]
-
- if badcount:
- print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors."
- print errmsg
- else:
- print " "+green("*")+" Processed",icount,"info files."
-
-
- def post_emerge(retval=0):
- global myopts
- os.chdir("/")
- if "--pretend" in myopts:
- sys.exit(retval)
-
- emergelog(" *** exiting successfully.")
-
- if "noinfo" not in portage.settings.features:
- chk_updated_info_files(retval)
-
- chk_updated_cfg_files()
- sys.exit(retval)
-
-
- def chk_updated_cfg_files():
- if portage.settings["CONFIG_PROTECT"]:
- #number of directories with some protect files in them
- procount=0
- for x in string.split(portage.settings["CONFIG_PROTECT"]):
- if os.path.isdir(x):
- a=commands.getstatusoutput("cd "+x+"; find . -iname '._cfg????_*'")
- if a[0]!=0:
- print " "+red("*")+" error scanning",x
- else:
- files=string.split(a[1])
- if files:
- procount=procount+1
- print " "+yellow("* IMPORTANT:")+"",len(files),"config files in",x,"need updating."
- if procount:
- #print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
- print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
- print
-
- def is_valid_package_atom(x):
- testkey = portage.dep_getkey(x)
- if testkey.startswith("null/"):
- testatom = x.replace(testkey[5:], "cat/"+testkey[5:])
- elif "/" not in x:
- testatom = "cat/"+x
- else:
- testatom = x
- return portage.isvalidatom(testatom)
-
- def validate_merge_list(mergelist):
- """Validate the list to make sure all the packages are still available.
- This is needed for --resume."""
- for (pkg_type, myroot, pkg_key, action) in mergelist:
- if pkg_type == "binary" and not portage.db["/"]["bintree"].dbapi.match("="+pkg_key) or \
- pkg_type == "ebuild" and not portage.db["/"]["porttree"].dbapi.xmatch("match-all", "="+pkg_key):
- print red("!!! Error: The resume list contains packages that are no longer")
- print red("!!! available to be emerged. Please restart/continue")
- print red("!!! the merge operation manually.")
- sys.exit(1)
-
- # general options that should be taken into account before any action
- if "--debug" in myopts:
- edebug=1
-
- if myaction in ["sync","metadata"] and (not "--help" in myopts):
- if "--pretend" in myopts:
- print "emerge: \"sync\" actions do not support \"--pretend.\""
- sys.exit(1)
-
- emergelog(" === "+str(myaction))
- myportdir=portage.settings["PORTDIR"]
- if myportdir[-1]=="/":
- myportdir=myportdir[:-1]
- if not os.path.exists(myportdir):
- print ">>>",myportdir,"not found, creating it."
- os.makedirs(myportdir,0755)
- syncuri=string.rstrip(portage.settings["SYNC"])
- os.umask(0022)
- if myaction == "metadata":
- if "--ask" in myopts:
- if userquery("Are you sure?") == "No":
- sys.exit(1)
- print "skipping sync"
- updatecache_flg = True
- tmpservertimestampfile = None
- elif syncuri[:8]=="rsync://":
- if not os.path.exists("/usr/bin/rsync"):
- print "!!! /usr/bin/rsync does not exist, so rsync support is disabled."
- print "!!! Type \"emerge net-misc/rsync\" to enable rsync support."
- sys.exit(1)
- mytimeout=180
-
- rsync_opts = []
-
- if portage.settings["PORTAGE_RSYNC_OPTS"] == "":
- portage.writemsg("PORTAGE_RSYNC_OPTS empty or unset, using hardcoded defaults\n")
- rsync_opts.extend([
- "--recursive", # Recurse directories
- "--links", # Consider symlinks
- "--safe-links", # Ignore links outside of tree
- "--perms", # Preserve permissions
- "--times", # Preserive mod times
- "--compress", # Compress the data transmitted
- "--force", # Force deletion on non-empty dirs
- "--whole-file", # Don't do block transfers, only entire files
- "--delete", # Delete files that aren't in the master tree
- "--delete-after", # Delete only after everything else is done
- "--stats", # Show final statistics about what was transfered
- "--timeout="+str(mytimeout), # IO timeout if not done in X seconds
- "--exclude='/distfiles'", # Exclude distfiles from consideration
- "--exclude='/local'", # Exclude local from consideration
- "--exclude='/packages'", # Exclude packages from consideration
- ])
-
- else:
- # The below validation is not needed when using the above hardcoded
- # defaults.
-
- portage.writemsg("Using PORTAGE_RSYNC_OPTS instead of hardcoded defaults\n", 1)
- rsync_opts.extend(portage.settings["PORTAGE_RSYNC_OPTS"].split())
-
- for opt in ("--recursive", "--times"):
- if opt not in rsync_opts:
- portage.writemsg(yellow("WARNING:") + " adding required option " + \
- "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
- rsync_opts.append(opt)
-
- for exclude in ("distfiles", "local", "packages"):
- opt = "--exclude='/%s'" % exclude
- if opt not in rsync_opts:
- portage.writemsg(yellow("WARNING:") + \
- " adding required option %s not included in " % opt + \
- "PORTAGE_RSYNC_OPTS (can be overridden with --exclude='!')\n")
- rsync_opts.append(opt)
-
- if portage.settings["RSYNC_TIMEOUT"] != "":
- portage.writemsg("WARNING: usage of RSYNC_TIMEOUT is deprecated, " + \
- "use PORTAGE_RSYNC_EXTRA_OPTS instead\n")
- try:
- mytimeout = int(portage.settings["RSYNC_TIMEOUT"])
- rsync_opts.append("--timeout=%d" % mytimeout)
- except ValueError, e:
- portage.writemsg("!!! %s\n" % str(e))
-
- # TODO: determine options required for official servers
- if syncuri.rstrip("/").endswith(".gentoo.org/gentoo-portage"):
-
- def rsync_opt_startswith(opt_prefix):
- for x in rsync_opts:
- if x.startswith(opt_prefix):
- return True
- return False
-
- if not rsync_opt_startswith("--timeout="):
- rsync_opts.append("--timeout=%d" % mytimeout)
-
- for opt in ("--compress", "--whole-file"):
- if opt not in rsync_opts:
- portage.writemsg(yellow("WARNING:") + " adding required option " + \
- "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
- rsync_opts.append(opt)
-
- if "--quiet" in myopts:
- rsync_opts.append("--quiet") # Shut up a lot
- else:
- rsync_opts.append("--verbose") # Print filelist
-
- if "--verbose" in myopts:
- rsync_opts.append("--progress") # Progress meter for each file
-
- if "--debug" in myopts:
- rsync_opts.append("--checksum") # Force checksum on all files
-
- if portage.settings["RSYNC_EXCLUDEFROM"] != "":
- portage.writemsg(yellow("WARNING:") + \
- " usage of RSYNC_EXCLUDEFROM is deprecated, use " + \
- "PORTAGE_RSYNC_EXTRA_OPTS instead\n")
- if os.path.exists(portage.settings["RSYNC_EXCLUDEFROM"]):
- rsync_opts.append("--exclude-from=%s" % \
- portage.settings["RSYNC_EXCLUDEFROM"])
- else:
- portage.writemsg("!!! RSYNC_EXCLUDEFROM specified," + \
- " but file does not exist.\n")
-
- if portage.settings["RSYNC_RATELIMIT"] != "":
- portage.writemsg(yellow("WARNING:") + \
- " usage of RSYNC_RATELIMIT is deprecated, use " + \
- "PORTAGE_RSYNC_EXTRA_OPTS instead")
- rsync_opts.append("--bwlimit=%s" % \
- portage.settings["RSYNC_RATELIMIT"])
-
- servertimestampdir = portage.settings.depcachedir+"/"
- servertimestampfile = portage.settings.depcachedir+"/timestamp.chk"
- tmpservertimestampdir = portage.settings["PORTAGE_TMPDIR"]+"/"
- tmpservertimestampfile = portage.settings["PORTAGE_TMPDIR"]+"/timestamp.chk"
-
- # We only use the backup if a timestamp exists in the portdir.
- content=None
- if os.path.exists(myportdir+"/metadata/timestamp.chk"):
- content=portage.grabfile(servertimestampfile)
- if (not content):
- content=portage.grabfile(myportdir+"/metadata/timestamp.chk")
-
- if (content):
- try:
- mytimestamp=time.mktime(time.strptime(content[0], "%a, %d %b %Y %H:%M:%S +0000"))
- except ValueError:
- mytimestamp=0
- else:
- mytimestamp=0
-
- if not os.path.exists(servertimestampdir):
- os.mkdir(servertimestampdir)
- os.chown(servertimestampdir, os.getuid(), portage.portage_gid)
- os.chmod(servertimestampdir, 02775)
-
- #exitcode=0
- try:
- if portage.settings.has_key("RSYNC_RETRIES"):
- print yellow("WARNING:")+" usage of RSYNC_RETRIES is deprecated, use PORTAGE_RSYNC_RETRIES instead"
- maxretries=int(portage.settings["RSYNC_RETRIES"])
- else:
- maxretries=int(portage.settings["PORTAGE_RSYNC_RETRIES"])
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- maxretries=3 #default number of retries
-
- retries=0
- hostname, port=re.split("rsync://([^:/]*)(:[0-9]+)?", syncuri)[1:3];
- if port is None:
- port=""
- updatecache_flg=True
-
- ips=[]
- while (1):
- if ips:
- del ips[0]
- if ips==[]:
- try:
- ips=socket.gethostbyname_ex(hostname)[2]
- except SystemExit, e:
- raise # Needed else can't exit
- except Exception, e:
- print "Notice:",str(e)
- dosyncuri=syncuri
-
- if ips:
- try:
- dosyncuri=string.replace(syncuri, "//"+hostname+port+"/", "//"+ips[0]+port+"/", 1)
- except SystemExit, e:
- raise # Needed else can't exit
- except Exception, e:
- print "Notice:",str(e)
- dosyncuri=syncuri
-
- if (retries==0):
- if "--ask" in myopts:
- if userquery("Do you want to sync your Portage tree with the mirror at\n" + blue(dosyncuri) + bold("?"))=="No":
- print
- print "Quitting."
- print
- sys.exit(0)
- emergelog(">>> Starting rsync with "+dosyncuri)
- if "--quiet" not in myopts:
- print ">>> Starting rsync with "+dosyncuri+"..."
- else:
- emergelog(">>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri))
- print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri)
-
- if "--quiet" not in myopts:
- print ">>> Checking server timestamp ..."
-
- rsynccommand = " ".join(["/usr/bin/rsync",
- portage.settings["PORTAGE_RSYNC_EXTRA_OPTS"],
- " ".join(rsync_opts)])
-
- if "--debug" in myopts:
- print rsynccommand
-
- mycommand = " ".join([rsynccommand,
- dosyncuri + "/metadata/timestamp.chk",
- tmpservertimestampdir])
- exitcode=portage.spawn(mycommand,portage.settings,free=1)
- if (exitcode==0):
- try:
- servertimestamp = time.mktime(time.strptime(portage.grabfile(tmpservertimestampfile)[0], "%a, %d %b %Y %H:%M:%S +0000"))
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- servertimestamp = 0
-
- if (servertimestamp != 0) and (servertimestamp == mytimestamp):
- emergelog(">>> Cancelling sync -- Already current.")
- print
- print ">>>"
- print ">>> Timestamps on the server and in the local repository are the same."
- print ">>> Cancelling all further sync action. You are already up to date."
- print ">>>"
- print
- sys.exit(0)
- elif (servertimestamp != 0) and (servertimestamp < mytimestamp):
- emergelog(">>> Server out of date: %s" % dosyncuri)
- print
- print ">>>"
- print ">>> SERVER OUT OF DATE: %s" % dosyncuri
- print ">>>"
- print
- elif (servertimestamp == 0) or (servertimestamp > mytimestamp):
- # actual sync
- mycommand=rsynccommand+" "+dosyncuri+"/ "+myportdir
- exitcode=portage.spawn(mycommand,portage.settings,free=1)
- if exitcode in [0,1,2,3,4,11,14,20,21]:
- break
- elif exitcode in [0,1,2,3,4,11,14,20,21]:
- break
-
- retries=retries+1
-
- if retries<=maxretries:
- print ">>> Retrying..."
- time.sleep(11)
- else:
- # over retries
- # exit loop
- updatecache_flg=False
- break
-
- if (exitcode==0):
- emergelog("=== Sync completed with %s" % dosyncuri)
- # save timestamp.chk for next timestamp check.
- try:
- if tmpservertimestampfile is not None:
- portage.movefile(tmpservertimestampfile,
- servertimestampfile)
- except SystemExit, e:
- raise
- except Exception, e:
- portage.writemsg("!!! Failed to save current timestamp.\n",
- noiselevel=-1)
- portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
- del e
- elif (exitcode>0):
- print
- if exitcode==1:
- print darkred("!!!")+green(" Rsync has reported that there is a syntax error. Please ensure")
- print darkred("!!!")+green(" that your SYNC statement is proper.")
- print darkred("!!!")+green(" SYNC="+portage.settings["SYNC"])
- elif exitcode==11:
- print darkred("!!!")+green(" Rsync has reported that there is a File IO error. Normally")
- print darkred("!!!")+green(" this means your disk is full, but can be caused by corruption")
- print darkred("!!!")+green(" on the filesystem that contains PORTDIR. Please investigate")
- print darkred("!!!")+green(" and try again after the problem has been fixed.")
- print darkred("!!!")+green(" PORTDIR="+portage.settings["PORTDIR"])
- elif exitcode==20:
- print darkred("!!!")+green(" Rsync was killed before it finished.")
- else:
- print darkred("!!!")+green(" Rsync has not successfully finished. It is recommended that you keep")
- print darkred("!!!")+green(" trying or that you use the 'emerge-webrsync' option if you are unable")
- print darkred("!!!")+green(" to use rsync due to firewall or other restrictions. This should be a")
- print darkred("!!!")+green(" temporary problem unless complications exist with your network")
- print darkred("!!!")+green(" (and possibly your system's filesystem) configuration.")
- print
- sys.exit(exitcode)
- elif syncuri[:6]=="cvs://":
- if not os.path.exists("/usr/bin/cvs"):
- print "!!! /usr/bin/cvs does not exist, so CVS support is disabled."
- print "!!! Type \"emerge dev-util/cvs\" to enable CVS support."
- sys.exit(1)
- cvsroot=syncuri[6:]
- cvsdir=os.path.dirname(myportdir)
- if not os.path.exists(myportdir+"/CVS"):
- #initial checkout
- print ">>> Starting initial cvs checkout with "+syncuri+"..."
- if os.path.exists(cvsdir+"/gentoo-x86"):
- print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting."
- sys.exit(1)
- if portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co -P gentoo-x86",portage.settings,free=1):
- print "!!! cvs checkout error; exiting."
- sys.exit(1)
- if cvsdir!=myportdir:
- portage.movefile(cvsdir,portage.settings["PORTDIR"])
- sys.exit(0)
- else:
- #cvs update
- print ">>> Starting cvs update with "+syncuri+"..."
- sys.exit(portage.spawn("cd "+myportdir+"; cvs -z0 -q update -dP",portage.settings,free=1))
- else:
- print "!!! rsync setting: ",syncuri,"not recognized; exiting."
- sys.exit(1)
-
- if updatecache_flg and \
- myaction != "metadata" and \
- "metadata-transfer" not in portage.settings.features:
- updatecache_flg = False
-
- if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg:
- if "--quiet" not in myopts:
- print "\n>>> Updating Portage cache: ",
- os.umask(0002)
- cachedir = os.path.normpath(portage.settings.depcachedir)
- if cachedir in ["/", "/bin", "/dev", "/etc", "/home",
- "/lib", "/opt", "/proc", "/root", "/sbin",
- "/sys", "/tmp", "/usr", "/var"]:
- print "!!! PORTAGE_CACHEDIR IS SET TO A PRIMARY ROOT DIRECTORY ON YOUR SYSTEM."
- print "!!! This is ALMOST CERTAINLY NOT what you want: "+str(cachedir)
- sys.exit(73)
- if not os.path.exists(cachedir):
- os.mkdir(cachedir)
-
- # Potentially bad
- #if os.path.exists(cachedir+"/"+myportdir):
- # portage.spawn("rm -Rf "+cachedir+"/"+myportdir+"/*",portage.settings,free=1)
-
- portage.portdb.flush_cache()
-
- ec = portage.eclass_cache.cache(portage.portdb.porttree_root)
- # kinda ugly.
- # XXX: nuke the filter when mr UNUSED_0? keys are dead
- cm = portage.settings.load_best_module("portdbapi.metadbmodule")(myportdir, "metadata/cache",
- filter(lambda x: not x.startswith("UNUSED_0"), portage.auxdbkeys))
-
- # we don't make overlay trees cache here, plus we don't trust portage.settings.categories
- porttree_root = portage.portdb.porttree_root
- conf = portage.config(config_profile_path=portage.settings.profile_path[:], \
- config_incrementals=portage.settings.incrementals[:])
-
- conf["PORTDIR_OVERLAY"] = ''
- conf.categories = portage.grabfile(os.path.join(porttree_root, "profiles", "categories"))
- try:
- i = conf.categories.index("virtual")
- if i != -1:
- conf.categories.remove(i)
- except (ValueError, IndexError):
- pass
-
- pdb = portage.portdbapi(porttree_root, conf)
-
- cp_all_list = pdb.cp_all()
- import cache.util
-
- class percentage_noise_maker(cache.util.quiet_mirroring):
- def __init__(self, dbapi):
- self.dbapi = dbapi
- self.cp_all = dbapi.cp_all()
- l = len(self.cp_all)
- self.call_update_min = 100000000
- self.min_cp_all = l/100.0
- self.count = 1
- self.pstr = ''
-
- def __iter__(self):
- for x in self.cp_all:
- self.count += 1
- if self.count > self.min_cp_all:
- self.call_update_min = 0
- self.count = 0
- for y in self.dbapi.cp_list(x):
- yield y
- self.call_update_mine = 0
-
- def update(self, *arg):
- try: self.pstr = int(self.pstr) + 1
- except ValueError: self.pstr = 1
- sys.stdout.write("%s%i%%" % ("\b" * (len(str(self.pstr))+1), self.pstr))
- sys.stdout.flush()
- self.call_update_min = 10000000
-
- def finish(self, *arg):
- sys.stdout.write("\b\b\b\b100%\n")
- sys.stdout.flush()
-
-
- if "--quiet" in myopts:
- def quicky_cpv_generator(cp_all_list):
- for x in cp_all_list:
- for y in pdb.cp_list(x):
- yield y
- source = quicky_cpv_generator(pdb.cp_all())
- noise_maker = cache.util.quiet_mirroring()
- else:
- noise_maker = source = percentage_noise_maker(pdb)
- cache.util.mirror_cache(source, cm, pdb.auxdb[porttree_root], eclass_cache=ec, verbose_instance=noise_maker)
-
- sys.stdout.flush()
-
- portage.portageexit()
- reload(portage)
- portage.global_updates(
- portage.settings, portage.db, portage.mtimedb["updates"])
- mybestpv=portage.portdb.xmatch("bestmatch-visible","sys-apps/portage")
- mypvs=portage.best(portage.db[portage.root]["vartree"].dbapi.match("sys-apps/portage"))
-
- chk_updated_cfg_files()
-
- if myaction != "metadata":
- if os.access(portage.USER_CONFIG_PATH + "/bin/post_sync", os.X_OK):
- try:
- portage.spawn(portage.USER_CONFIG_PATH + "/bin/post_sync " + dosyncuri, portage.settings, free=1)
- except:
- print red(" * ")+bold("spawn failed of "+ portage.USER_CONFIG_PATH + "/bin/post_sync")
-
- if(mybestpv != mypvs) and not "--quiet" in myopts:
- print
- print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended"
- print red(" * ")+"that you update portage now, before any other packages are updated."
- print red(" * ")+"Please run 'emerge portage' and then update "+bold("ALL")+" of your"
- print red(" * ")+"configuration files."
- print red(" * ")+"To update portage, run 'emerge portage'."
- print
- elif myaction=="regen":
- emergelog(" === regen")
- #regenerate cache entries
- print "Regenerating cache entries... "
- try:
- os.close(sys.stdin.fileno())
- except SystemExit, e:
- raise # Needed else can't exit
- except:
- pass
- sys.stdout.flush()
- mynodes=portage.portdb.cp_all()
- for x in mynodes:
- mymatches=portage.portdb.xmatch("match-all",x)
- if not "--quiet" in myopts:
- print "processing",x
- for y in mymatches:
- try:
- foo=portage.portdb.aux_get(y,["DEPEND"])
- except SystemExit, e:
- # sys.exit is an exception... And consequently, we can't catch it.
- raise
- except Exception, e:
- print "\n error processing %(cpv)s, continuing... (%(e)s)" % {"cpv":y,"e":str(e)}
- print "done!"
- # HELP action
- elif "config"==myaction:
- if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
- print red("!!! config can only take a single package atom at this time\n")
- sys.exit(1)
- if not is_valid_package_atom(myfiles[0]):
- portage.writemsg("!!! '%s' is not a valid package atom.\n" % myfiles[0],
- noiselevel=-1)
- portage.writemsg("!!! Please check ebuild(5) for full details.\n")
- portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
- sys.exit(1)
- print
- try:
- pkgs = portage.db[portage.root]["vartree"].dbapi.match(myfiles[0])
- except ValueError, e:
- # Multiple matches thrown from cpv_expand
- pkgs = e.args[0]
- if len(pkgs) == 0:
- print "No packages found.\n"
- sys.exit(0)
- elif len(pkgs) > 1:
- if "--ask" in myopts:
- options = []
- print "Please select a package to configure:"
- idx = 0
- for pkg in pkgs:
- idx += 1
- options.append(str(idx))
- print options[-1]+") "+pkg
- print "X) Cancel"
- options.append("X")
- idx = userquery("Selection?", options)
- if idx == "X":
- sys.exit(0)
- pkg = pkgs[int(idx)-1]
- else:
- print "The following packages available:"
- for pkg in pkgs:
- print "* "+pkg
- print "\nPlease use a specific atom or the --ask option."
- sys.exit(1)
- else:
- pkg = pkgs[0]
-
- print
- if "--ask" in myopts:
- if userquery("Ready to configure "+pkg+"?") == "No":
- sys.exit(0)
- else:
- print "Configuring pkg..."
- print
- ebuildpath = portage.db[portage.root]["vartree"].dbapi.findname(pkg)
- mysettings = portage.config(clone=portage.settings)
- portage.doebuild(ebuildpath,"config",portage.root,mysettings,debug=("--debug" in myopts),cleanup=True,tree="vartree")
- print
-
- # INFO action
- elif "info"==myaction:
- unameout=commands.getstatusoutput("uname -mrp")[1]
- print getportageversion()
- print "================================================================="
- print "System uname: "+unameout
- if os.path.exists("/etc/gentoo-release"):
- os.system("cat /etc/gentoo-release")
- else:
- print "Unknown Host Operating System"
-
- output=commands.getstatusoutput("distcc --version")
- if not output[0]:
- print str(string.split(output[1],"\n",1)[0]),
- if "distcc" in portage.settings.features:
- print "[enabled]"
- else:
- print "[disabled]"
-
- output=commands.getstatusoutput("ccache -V")
- if not output[0]:
- print str(string.split(output[1],"\n",1)[0]),
- if "ccache" in portage.settings.features:
- print "[enabled]"
- else:
- print "[disabled]"
-
- myvars = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers",
- "sys-devel/binutils", "sys-devel/libtool", "dev-lang/python"]
- myvars += portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_pkgs")
- myvars = portage_util.unique_array(myvars)
- myvars.sort()
-
- for x in myvars:
- if portage.isvalidatom(x):
- pkg_matches = portage.db["/"]["vartree"].dbapi.match(x)
- pkgs = []
- for y in pkg_matches:
- mycpv = portage.catpkgsplit(y)
- if(mycpv[3] != "r0"):
- pkgs += [mycpv[2] + "-" + mycpv[3]]
- else:
- pkgs += [mycpv[2]]
- if not pkgs:
- pkgs = "[Not Present]"
- else:
- pkgs = ", ".join(sorted_versions(pkgs))
- print "%-20s %s" % (x+":", pkgs)
- else:
- print "%-20s %s" % (x+":", "[NOT VALID]")
-
- libtool_vers = string.join(portage.db["/"]["vartree"].dbapi.match("sys-devel/libtool"), ",")
-
- if "--verbose" in myopts:
- myvars=portage.settings.keys()
- else:
- myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK',
- 'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR',
- 'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS',
- 'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES', 'EMERGE_DEFAULT_OPTS']
-
- myvars.extend(portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_vars"))
-
- myvars = portage_util.unique_array(myvars)
- unset_vars = []
- myvars.sort()
- for x in myvars:
- if portage.settings.has_key(x):
- print x+'="'+portage.settings[x]+'"'
- else:
- unset_vars.append(x)
- if unset_vars:
- print "Unset: "+", ".join(unset_vars)
- print
-
- if "--debug" in myopts:
- for x in dir(portage):
- module = getattr(portage, x)
- if "cvs_id_string" in dir(module):
- print "%s: %s" % (str(x), str(module.cvs_id_string))
-
- # SEARCH action
- elif "search"==myaction:
- if not myfiles:
- print "emerge: no search terms provided."
- else:
- searchinstance = search()
- for mysearch in myfiles:
- try:
- searchinstance.execute(mysearch)
- except re.error, comment:
- print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment )
- sys.exit(1)
- searchinstance.output()
- elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction:
- if 1 == unmerge(myaction, myfiles, raise_on_missing=False):
- post_emerge()
-
- elif "depclean"==myaction:
- # Kill packages that aren't explicitly merged or are required as a
- # dependency of another package. World file is explicit.
-
- print
- print red("*** WARNING ***")+" --depclean is known to be broken. It is highly recommended"
- print red("*** WARNING ***")+" that "+green("`emerge --update --newuse --deep world`")+" be ran before"
- print red("*** WARNING ***")+" commencing. However, using --depclean may still break link"
- print red("*** WARNING ***")+" level consistency within your system. "+green("`revdep-rebuild`")
- print red("*** WARNING ***")+" from app-portage/gentoolkit can help to detect breakage."
- print red("*** WARNING ***")
- print red("*** WARNING ***")+" Also study the list of packages to be cleaned for any"
- print red("*** WARNING ***")+" obvious mistakes. Packages can be manually added to the"
- print red("*** WARNING ***")+" world list by running "+green("`emerge --noreplace <atom>`")+"."
- print red("*** WARNING ***")
- print red("*** WARNING ***")+" It is normal for packages that are masked or listed in"
- print red("*** WARNING ***")+" package.provided to be removed by depclean. These are the most"
- print red("*** WARNING ***")+" likely reasons that depclean will remove a package even though"
- print red("*** WARNING ***")+" it is in the world or system package set. In order to"
- print red("*** WARNING ***")+" troubleshoot these types of problems, it is often helpful to"
- print red("*** WARNING ***")+" look at the output of "+green("`grep -r <atom> /etc/portage`")+"."
- print red("*** WARNING ***")
- print red("*** WARNING ***")+" "+bold("Make sure you have a backup.")
-
- syslist=getlist("system")
- worldlist=getlist("world")
- myvarlist=portage.vardbapi(portage.root).cp_all()
-
- if not syslist:
- print "\n!!! You have no system list.",
- if not worldlist:
- print "\n!!! You have no world file.",
- if not myvarlist:
- print "\n!!! You have no installed package database (%s)." % portage.VDB_PATH,
-
- if not (syslist and worldlist and myvarlist):
- print "\n!!! Proceeding will break your installation.\n"
- countdown(EMERGE_WARNING_DELAY, ">>> Depclean")
-
- if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
- emergelog(" >>> depclean")
-
- mydepgraph=depgraph(myaction,myopts)
-
- if not ("--quiet" in myopts):
- print "\nCalculating dependencies ",
- if not mydepgraph.xcreate("world"):
- print "\n!!! Failed to create deptree."
- sys.exit(1)
- if not ("--quiet" in myopts):
- print "\b\b... done!"
-
- if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
- sys.stderr.write(red("The following binaries are not available for merging...\n"))
- for x in mydepgraph.missingbins:
- sys.stderr.write(" "+str(x)+"\n")
- sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
- sys.exit(1)
-
- alldeps=mydepgraph.digraph.allnodes()
-
- if not alldeps:
- print "!!! You have no dependencies. Impossible. Bug."
- sys.exit(1)
-
- reallist=[]
- for x in alldeps:
- myparts=portage.catpkgsplit(string.split(x)[2])
- if not myparts:
- sys.stderr.write(
- red("!!! There appears to be a problem with the following package:\n")+
- red("!!! "+str(string.split(x)[2])+"\n\n")+
- "!!! Please ensure that blocking/conflicting packages are not merged."+
- "!!! 'emerge -p "+str(string.split(x)[2])+"\n\n")
- if ("--pretend" not in myopts) and ("--ask" not in myopts):
- countdown(EMERGE_WARNING_DELAY, "*** Continuing")
- continue
-
- catpack=myparts[0]+"/"+myparts[1]
- if catpack not in reallist:
- reallist.append(catpack)
-
- cleanlist=[]
- for x in myvarlist:
- if x not in reallist:
- if x not in cleanlist:
- cleanlist.append(x)
-
- for x in syslist+worldlist:
- myparts = portage.catpkgsplit(x)
- if myparts:
- if myparts[0][0] in ('<','>','='):
- myparts[0] = myparts[0][1:]
- if myparts[0][0] in ('<','>','='):
- myparts[0] = myparts[0][1:]
- catpack=myparts[0]+"/"+myparts[1]
- else:
- catpack=x
- if catpack in cleanlist:
- cleanlist.remove(catpack)
-
- #print "\n\n\nCleaning: "
- #for x in cleanlist:
- # print x
- #print
-
- if len(cleanlist):
- unmerge("unmerge", cleanlist)
-
- print
- print "Packages installed: "+str(len(myvarlist))
- print "Packages in world: "+str(len(worldlist))
- print "Packages in system: "+str(len(syslist))
- print "Unique package names: "+str(len(reallist))
- print "Required packages: "+str(len(alldeps))
- if "--pretend" in myopts:
- print "Number to remove: "+str(len(cleanlist))
- else:
- print "Number removed: "+str(len(cleanlist))
- post_emerge()
-
- # "update", "system", or just process files:
- else:
- favorites=[]
- syslist=getlist("system")
- if ("--ask" in myopts or "--pretend" in myopts) and not "--quiet" in myopts:
- action = ""
- if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
- action = "fetched"
- else:
- action = "merged"
- if "--tree" in myopts and action != "fetched": # Tree doesn't work with fetching
- print
- print darkgreen("These are the packages that would be %s, in reverse order:") % action
- print
- else:
- print
- print darkgreen("These are the packages that would be %s, in order:") % action
- print
-
- if "--resume" in myopts and \
- ("resume" in portage.mtimedb or
- "resume_backup" in portage.mtimedb):
- if "resume" not in portage.mtimedb:
- portage.mtimedb["resume"] = portage.mtimedb["resume_backup"]
- del portage.mtimedb["resume_backup"]
- portage.commit_mtimedb()
- myresumeopts=portage.mtimedb["resume"]["myopts"][:]
-
- for opt in ("--skipfirst", "--ask", "--tree"):
- while opt in myresumeopts:
- myresumeopts.remove(opt)
-
- for myopt in myopts:
- if myopt not in myresumeopts:
- myresumeopts.append(myopt)
- myopts=myresumeopts
- mydepgraph=depgraph("resume",myopts)
- if "--resume" not in myopts:
- myopts+=["--resume"]
- else:
- if ("--resume" in myopts):
- del myopts[myopts.index("--resume")]
- print darkgreen("emerge: It seems we have nothing to resume...")
- sys.exit(0)
-
- mydepgraph=depgraph(myaction,myopts)
- if myaction in ["system","world"]:
- if not ("--quiet" in myopts):
- print "Calculating",myaction,"dependencies ",
- sys.stdout.flush()
- if not mydepgraph.xcreate(myaction):
- print "!!! Depgraph creation failed."
- sys.exit(1)
- if not ("--quiet" in myopts):
- print "\b\b... done!"
- else:
- if not ("--quiet" in myopts):
- print "Calculating dependencies ",
- sys.stdout.flush()
- try:
- retval, favorites = mydepgraph.select_files(myfiles)
- except portage_exception.PackageNotFound, e:
- portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1)
- sys.exit(1)
- if not retval:
- sys.exit(1)
- if not ("--quiet" in myopts):
- print "\b\b... done!"
-
- if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
- sys.stderr.write(red("The following binaries are not available for merging...\n"))
-
- if mydepgraph.missingbins:
- for x in mydepgraph.missingbins:
- sys.stderr.write(" "+str(x)+"\n")
- sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
- sys.exit(1)
-
- if "--ask" in myopts:
- if "--resume" in myopts:
- validate_merge_list(portage.mtimedb["resume"]["mergelist"])
- mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
- prompt="Would you like to resume merging these packages?"
- else:
- mydepgraph.display(mydepgraph.altlist())
- mergecount=0
- for x in mydepgraph.altlist():
- if x[3]!="nomerge":
- mergecount+=1
- #check for blocking dependencies
- if x[0]=="blocks" and "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts:
- print "\n!!! Error: The above package list contains packages which cannot be installed"
- print "!!! at the same time on the same system."
- print
- sys.exit(1)
- if mergecount==0:
- if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
- prompt="Nothing to merge; would you like to auto-clean packages?"
- else:
- print
- print "Nothing to merge; quitting."
- print
- sys.exit(0)
- elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
- prompt="Would you like to fetch the source files for these packages?"
- else:
- prompt="Would you like to merge these packages?"
- print
- if userquery(prompt)=="No":
- print
- print "Quitting."
- print
- sys.exit(0)
- # Don't ask again (e.g. when auto-cleaning packages after merge)
- myopts.remove("--ask")
-
- if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
- if ("--resume" in myopts):
- validate_merge_list(portage.mtimedb["resume"]["mergelist"])
- mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
- else:
- mydepgraph.display(mydepgraph.altlist())
- else:
- if ("--buildpkgonly" in myopts):
- if not mydepgraph.digraph.hasallzeros():
- print "\n!!! --buildpkgonly requires all dependencies to be merged."
- print "!!! Cannot merge requested packages. Merge deps and try again.\n"
- sys.exit(1)
-
- if ("--resume" in myopts):
- favorites=portage.mtimedb["resume"]["favorites"]
- mydepgraph.merge(portage.mtimedb["resume"]["mergelist"])
- else:
- if "resume" in portage.mtimedb and \
- "mergelist" in portage.mtimedb["resume"] and \
- len(portage.mtimedb["resume"]["mergelist"]) > 1:
- portage.mtimedb["resume_backup"] = portage.mtimedb["resume"]
- del portage.mtimedb["resume"]
- portage.commit_mtimedb()
- portage.mtimedb["resume"]={}
- portage.mtimedb["resume"]["myopts"]=myopts
- portage.mtimedb["resume"]["favorites"]=favorites
- if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
- for pkgline in mydepgraph.altlist():
- if pkgline[0]=="ebuild" and pkgline[3]=="merge":
- y=portage.portdb.findname(pkgline[2])
- tmpsettings = portage.config(clone=portage.settings)
- retval=portage.doebuild(y,"digest",portage.root,tmpsettings,edebug,("--pretend" in myopts),tree="porttree")
- if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
- pkglist = []
- for pkg in mydepgraph.altlist():
- if pkg[0] != "blocks":
- pkglist.append(pkg)
- else:
- pkglist = mydepgraph.altlist()
- mydepgraph.merge(pkglist)
-
- if portage.mtimedb.has_key("resume"):
- del portage.mtimedb["resume"]
- if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
- print ">>> Auto-cleaning packages..."
- unmerge("clean", ["world"])
- else:
- portage.writemsg_stdout(colorize("WARN", "WARNING:")
- + " AUTOCLEAN is disabled. This can cause serious"
- + " problems due to overlapping packages.\n")
- post_emerge()
-